Oct 3, 2026·6 min read·8 visits
An asymmetric authorization gap in Trigger.dev allows low-privilege development keys to cancel high-privilege production deployments due to a missing environment-level scoping filter on write actions.
A logical authorization bypass vulnerability exists in Trigger.dev versions prior to 4.5.6. This flaw allows an authenticated client with a low-trust environment API key, such as development or staging, to cancel active worker deployments in a higher-trust environment like production within the same project. The vulnerability occurs because write operations on deployments were scoped solely by project identifier instead of environment identifier.
Trigger.dev utilizes a multi-environment architecture to segregate execution environments, dividing them into distinct tiers such as development, staging, and production. Each individual environment is assigned a unique, high-entropy API key that establishes a security boundary. This model assumes that development keys are lower trust compared to production keys.
This architecture is designed to prevent cross-environment tampering. However, a logical flaw was identified where the backend service did not enforce strict environment isolation during the deployment cancellation process. As a result, an attacker possessing an API key for a low-trust environment could successfully cancel active deployments in a production environment.
The vulnerability represents a breakdown in horizontal privilege escalation protection. It is cataloged as a logical authorization bypass. The root cause lies in the application of project-level scopes rather than environment-level scopes on write operations. This exposes active deployments to unauthorized cross-environment interference.
In the relational database schema of Trigger.dev, a single project can contain multiple environments. Each deployment is associated with both a specific environment ID and a general project ID. To enforce correct access controls, operations must authenticate against both parameters to guarantee the request originates from the matching environment context.
The vulnerability occurs because the getDeployment database query inside the deployment management service was implemented using only the projectId and the deployment friendlyId. While this query successfully restricted operations to the correct tenant, it completely bypassed the finer-grained environment check. Consequently, any authenticated key belonging to any environment in that project could retrieve and modify any deployment record.
This issue presents a stark contrast to the corresponding GET endpoint which retrieves deployment details. The read endpoint correctly verifies that the requested deployment matches the environmentId of the caller. This asymmetry allowed an API key to write and modify a resource that it was completely unauthorized to view.
The vulnerable implementation of the deployment service relied on a helper function that lacked the environment parameter. In apps/webapp/app/v3/services/deployment.server.ts, the database query was defined to filter only on the project identifier and the deployment identifier:
// Vulnerable method signature and database query
private getDeployment(projectId: string, friendlyId: string) {
return this._prisma.workerDeployment.findFirst({
where: {
friendlyId,
projectId, // Only scopes query to the parent project
},
});
}This implementation was refactored in version 4.5.6 to accept and enforce the environment ID. The patched code introduces the environmentId parameter into the helper function, modifying the Prisma selector to restrict the query dynamically to the exact authenticated environment:
// Patched method signature enforcing environment isolation
private getDeployment(environmentId: string, friendlyId: string) {
return fromPromise(
this._prisma.workerDeployment.findFirst({
where: {
friendlyId,
environmentId, // Restricts lookup to the authenticated environment
},
select: {
status: true,
id: true,
}
})
);
}The patch completely mitigates the logical bypass by shifting the authorization anchor from project level to environment level. Security teams have verified that this fix prevents cross-environment cancellation requests. Additionally, related routes such as credential generation endpoints were updated with identical environment constraints to ensure uniform enforcement.
An exploitation scenario requires the attacker to possess a valid API key for a low-trust environment within the target project. The attacker must also identify the target deployment identifier, which is typically formatted as a structured string. Because the read endpoint is secure, this identifier must be obtained via secondary channels such as build logs, monitoring tools, or administrative portals.
To perform the attack, the adversary initiates a POST request directly to the deployment cancellation endpoint of the Trigger.dev API. The request is authorized using the developer API key, which passes the project-level validation check:
POST /api/v1/deployments/deployment_pocvictim/cancel HTTP/1.1
Host: api.trigger.dev
Authorization: Bearer tr_dev_examplekey123
Content-Type: application/jsonThe backend processes this request, retrieves the target deployment because it shares the same project ID, and transitions its database state to the canceled status. The server returns a success response, confirming the modification. If the attacker attempts this action on a deployment belonging to a completely different project, the request fails with a 404 status.
The vulnerability has been assigned a CVSS score of 5.4, indicating medium severity. The primary security impact is focused on availability and integrity, with no impact on confidentiality. Because read requests on deployments are correctly validated, attackers cannot view environment variables, secret tokens, or private build logs using this vulnerability.
The degradation of integrity lies in the unauthorized modification of deployment states from pending or active status to canceled. This allows malicious actors to prematurely terminate critical builds. The availability threat is significant for organizations relying on automated continuous deployment systems, as an attacker can systematically block all update paths.
The scope of the vulnerability remains unchanged because it does not allow cross-tenant operations. Attackers are restricted to environments within projects where they already hold valid API keys. The primary risk is insider threats or compromised development pipelines where low-trust keys are exposed to developers or CI scripts.
The primary remediation strategy is to upgrade all Trigger.dev instances to version 4.5.6 or later. This release updates the core service files to enforce strict environment isolation across all write pathways. Administrators can verify dependency configurations in package.json to ensure the core libraries match the patched version:
{
"dependencies": {
"@trigger.dev/core": "^4.5.6"
}
}For self-hosted instances, administrative teams must redeploy the platform container instances using the updated images from the official registry. It is recommended to rotate all existing development and preview environment keys to invalidate any credentials that might have been compromised prior to the patch.
In addition to applying the patch, organizations should implement the least privilege principle by limiting the distribution of environment keys. Restricting API key visibility within CI/CD configuration panels reduces the risk of accidental exposure. Implementing monitoring on the cancellation endpoints can also alert security teams to unexpected cross-environment access patterns.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:L| Product | Affected Versions | Fixed Version |
|---|---|---|
trigger.dev Trigger.dev | <= 4.5.5 | 4.5.6 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-639 |
| Attack Vector | Network |
| CVSS | 5.4 |
| Impact | Integrity and Availability (Partial) |
| Exploit Status | Proof-of-Concept (PoC) available |
| KEV Status | Not Listed |
The system fails to prevent a user from accessing or modifying resources of another environment by using user-controlled parameters inside a project scope.
A path traversal vulnerability (CWE-22) in Contao CMS allows unauthenticated remote attackers to bypass directory boundary restrictions in ImagesController and access files within the project directory.
Contao Open Source CMS versions 4.0.0 through 5.3.49 and 5.4.0-RC1 through 5.7.11 contain a Cross-Site Request Forgery (CSRF) vulnerability in backend parameter handling. The `RequestTokenListener` component validates anti-CSRF tokens solely for HTTP POST requests, while GET-based declarative guards run only when an `act` parameter is present in the query string. Consequently, custom backend actions dispatched via alternative parameters such as `key=` can execute without CSRF token verification when triggered by an authenticated user.
Contao CMS versions 4.1.0 through 5.3.49 and 5.4.0-RC1 through 5.7.11 fail to validate form submission tokens and enforce rate limiting when processing activation email resend requests via HTTP POST, enabling resource exhaustion and account state enumeration.
An information disclosure vulnerability in Contao CMS allows unauthenticated site visitors to view protected page titles, URLs, and text excerpts through search queries when protected page indexing is disabled after previously being enabled.
In Vikunja prior to version 2.6.0, relation creation via the CalDAV endpoint fails to invoke the TaskRelation.CanCreate authorization check. This missing access control allows an authenticated user to establish unauthorized relationships and perform write operations against any task, provided its unique identifier (UID) is known.
A cross-project information disclosure vulnerability in Vikunja allows authenticated users with read access to one project to view private task details from unauthorized projects via subtask expansion parameters.