CVE-2026-73654
Trigger.dev: Prototype pollution via run metadata operations → process-wide cross-tenant DoS
Trigger.dev is a platform for building and deploying fully managed AI agents and workflows. From 3.3.8 until 4.5.6, the PUT /api/v1/runs/:runId/metadata endpoint passes attacker-controlled operation.key values to new JSONHeroPath(operation.key).set(newMetadata, value) in packages/core/src/v3/runMetadata/operations.ts without rejecting dangerous constructor and prototype path segments. A caller with a normal environment API key can pollute Object.prototype in the shared webapp process, corrupting Prisma queries and Prometheus labels, breaking other tenants' worker authentication, and causing a process-wide denial of service. This issue is fixed in version 4.5.6.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- Low
- User interaction
- None
What an attacker can affect
- Confidentiality
- None
- Integrity
- Low
- Availability
- High
Exploit likelihood
What each source reports
CVE List Score used
8.5
Trigger.dev: Prototype pollution via run metadata operations → process-wide cross-tenant DoS
Trigger.dev is a platform for building and deploying fully managed AI agents and workflows. From 3.3.8 until 4.5.6, the PUT /api/v1/runs/:runId/metadata endpoint passes attacker-controlled operation.key values to new JSONHeroPath(operation.key).set(newMetadata, value) in packages/core/src/v3/runMetadata/operations.ts without rejecting dangerous constructor and prototype path segments. A caller with a normal environment API key can pollute Object.prototype in the shared webapp process, corrupting Prisma queries and Prometheus labels, breaking other tenants' worker authentication, and causing a process-wide denial of service. This issue is fixed in version 4.5.6.
- Record
CVE-2026-73654- CVSS 3.1
- 8.5 High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:N/I:L/A:H - Weakness
- CWE-1321
- Updated
- 2026-11-02
EUVDEUVD-2026-58358
8.5
Trigger.dev is a platform for building and deploying fully managed AI agents and workflows. From 3.3.8 until 4.5.6, the PUT /api/v1/runs/:runId/metadata endpoint passes attacker-controlled operation.key values to new JSONHeroPath(operation.key).set(newMetadata, value) in packages/core/src/v3/runMetadata/operations.ts without rejecting dangerous constructor and prototype path segments. A caller with a normal environment API key can pollute Object.prototype in the shared webapp process, corrupting Prisma queries and Prometheus labels, breaking other tenants' worker authentication, and causing a process-wide denial of service. This issue is fixed in version 4.5.6.
- Record
EUVD-2026-58358- CVSS 3.1
- 8.5 High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:N/I:L/A:H - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-p28v-f755-9qrg
8.5
Trigger.dev: Prototype pollution via run metadata operations → process-wide cross-tenant DoS
Summary
The run-metadata update endpoint PUT /api/v1/runs/:runId/metadata applies client-supplied
"operations" by passing the attacker-controlled operation.key straight into
new JSONHeroPath(operation.key).set(newMetadata, value)
(packages/core/src/v3/runMetadata/operations.ts:22-23), with no prototype-pollution guard
(@jsonhero/path@^1.0.21 does not reject __proto__/constructor/prototype).
A request with key: "$.__proto__.polluted" sets Object.prototype.polluted in the webapp
process. Because every plain object then inherits that property, it corrupts unrelated code
process-wide and across tenants — including Prisma query building and the Prometheus metrics
client — causing query failures, broken authentication for other tenants' workers, and an
uncaughtException (denial of service). Only a normal, low-privilege environment API key is
required (one request).
Severity
A single request from any holder of a normal environment API key contaminates Object.prototype
in the shared webapp process, breaking other tenants' workers (scope change) and degrading/
crashing the process (high availability impact). Prototype pollution is also a primitive for
further gadget chains (integrity/confidentiality).
Affected versions
- Introduced in commit
34f8bd588("Add ability to update parent and root run metadata from children", PR #1563, 2025-01-08) — theJSONHeroPath(operation.key).set()sink is present from the first commit ofoperations.ts. SDK was at3.3.8at that time. - Still present at HEAD (SDK
4.5.0-rc.7);operations.tsunchanged since 2025-05, and@jsonhero/pathis pinned at^1.0.21(no proto-guard) throughout. - Affected range:
>= v3.3.8(metadata operations API) throughv4-beta/ current v4.x — fixed: 4.5.6.
Root cause
packages/core/src/v3/runMetadata/operations.ts — applyMetadataOperations() builds a path from
the untrusted operation.key and writes to it, for every operation type (set, append,
increment, …):
const path = new JSONHeroPath(operation.key); // operation.key fully attacker-controlled
path.set(newMetadata, operation.value); // no __proto__/constructor/prototype rejection
The request schema (UpdateMetadataRequestBody) types key as a plain string with no validation,
and @jsonhero/[email protected] walks __proto__ as an ordinary segment → the assignment lands on
Object.prototype.
Proof of Concept
Self-host ghcr.io/triggerdotdev/trigger.dev:v4-beta. Authenticated with a normal environment
API key (tr_dev_…) and any run id of that environment.
curl -X PUT "http://localhost:8030/api/v1/runs/run_cmqr2bsyo00013js2twwhdsfu/metadata" \
-H "Authorization: Bearer tr_dev_<env_key>" -H "Content-Type: application/json" \
--data '{"operations":[{"type":"set","key":"$.__proto__.polluted","value":"PWNED"}]}'
Result — Object.prototype.polluted = "PWNED" process-wide. Observed in the webapp logs:
- The request's own query is corrupted —
polluted:"PWNED"injected into every object Prisma enumerates:prisma.taskRun.updateMany({ where:{ id:"…", metadataVersion:2, polluted:"PWNED" }, data:{ …, metadataVersion:{ increment:1, polluted:"PWNED" }, polluted:"PWNED" }, polluted:"PWNED" }) -> Unknown argument `polluted` - Cross-tenant authentication break — the next request from a different client (a worker's
POST /engine/v1/dev/dequeue) fails insidefindEnvironmentByApiKey:
i.e. one tenant's request breaks authentication for other tenants' workers → their jobs stop being dequeued/processed.prisma.runtimeEnvironment.findFirst({ where:{ apiKey:"…", polluted:"PWNED" }, include:{ project:true, …, polluted:"PWNED" } }) -> PrismaClientValidationError - Denial of service — full process crash. The
uncaughtExceptionin prom-client (`Error: Added…
- Record
GHSA-p28v-f755-9qrg- CVSS 3.1
- 8.5 High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:N/I:L/A:H - Weakness
- CWE-1321
- Updated
- 2026-11-02
NVD
8.5
Trigger.dev is a platform for building and deploying fully managed AI agents and workflows. From 3.3.8 until 4.5.6, the PUT /api/v1/runs/:runId/metadata endpoint passes attacker-controlled operation.key values to new JSONHeroPath(operation.key).set(newMetadata, value) in packages/core/src/v3/runMetadata/operations.ts without rejecting dangerous constructor and prototype path segments. A caller with a normal environment API key can pollute Object.prototype in the shared webapp process, corrupting Prisma queries and Prometheus labels, breaking other tenants' worker authentication, and causing a process-wide denial of service. This issue is fixed in version 4.5.6.
- Record
CVE-2026-73654- CVSS 3.1
- 8.5 High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:N/I:L/A:H - Weakness
- CWE-1321
- Updated
- 2026-11-02
OSV
8.5
Trigger.dev: Prototype pollution via run metadata operations → process-wide cross-tenant DoS
Trigger.dev is a platform for building and deploying fully managed AI agents and workflows. From 3.3.8 until 4.5.6, the PUT /api/v1/runs/:runId/metadata endpoint passes attacker-controlled operation.key values to new JSONHeroPath(operation.key).set(newMetadata, value) in packages/core/src/v3/runMetadata/operations.ts without rejecting dangerous constructor and prototype path segments. A caller with a normal environment API key can pollute Object.prototype in the shared webapp process, corrupting Prisma queries and Prometheus labels, breaking other tenants' worker authentication, and causing a process-wide denial of service. This issue is fixed in version 4.5.6.
- Record
CVE-2026-73654- CVSS 3.1
- 8.5 High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:N/I:L/A:H - Weakness
- CWE-1321
- Updated
- 2026-11-02
OSVGHSA-p28v-f755-9qrg
8.5
Trigger.dev: Prototype pollution via run metadata operations → process-wide cross-tenant DoS
Summary
The run-metadata update endpoint PUT /api/v1/runs/:runId/metadata applies client-supplied
"operations" by passing the attacker-controlled operation.key straight into
new JSONHeroPath(operation.key).set(newMetadata, value)
(packages/core/src/v3/runMetadata/operations.ts:22-23), with no prototype-pollution guard
(@jsonhero/path@^1.0.21 does not reject __proto__/constructor/prototype).
A request with key: "$.__proto__.polluted" sets Object.prototype.polluted in the webapp
process. Because every plain object then inherits that property, it corrupts unrelated code
process-wide and across tenants — including Prisma query building and the Prometheus metrics
client — causing query failures, broken authentication for other tenants' workers, and an
uncaughtException (denial of service). Only a normal, low-privilege environment API key is
required (one request).
Severity
A single request from any holder of a normal environment API key contaminates Object.prototype
in the shared webapp process, breaking other tenants' workers (scope change) and degrading/
crashing the process (high availability impact). Prototype pollution is also a primitive for
further gadget chains (integrity/confidentiality).
Affected versions
- Introduced in commit
34f8bd588("Add ability to update parent and root run metadata from children", PR #1563, 2025-01-08) — theJSONHeroPath(operation.key).set()sink is present from the first commit ofoperations.ts. SDK was at3.3.8at that time. - Still present at HEAD (SDK
4.5.0-rc.7);operations.tsunchanged since 2025-05, and@jsonhero/pathis pinned at^1.0.21(no proto-guard) throughout. - Affected range:
>= v3.3.8(metadata operations API) throughv4-beta/ current v4.x — fixed: 4.5.6.
Root cause
packages/core/src/v3/runMetadata/operations.ts — applyMetadataOperations() builds a path from
the untrusted operation.key and writes to it, for every operation type (set, append,
increment, …):
const path = new JSONHeroPath(operation.key); // operation.key fully attacker-controlled
path.set(newMetadata, operation.value); // no __proto__/constructor/prototype rejection
The request schema (UpdateMetadataRequestBody) types key as a plain string with no validation,
and @jsonhero/[email protected] walks __proto__ as an ordinary segment → the assignment lands on
Object.prototype.
Proof of Concept
Self-host ghcr.io/triggerdotdev/trigger.dev:v4-beta. Authenticated with a normal environment
API key (tr_dev_…) and any run id of that environment.
curl -X PUT "http://localhost:8030/api/v1/runs/run_cmqr2bsyo00013js2twwhdsfu/metadata" \
-H "Authorization: Bearer tr_dev_<env_key>" -H "Content-Type: application/json" \
--data '{"operations":[{"type":"set","key":"$.__proto__.polluted","value":"PWNED"}]}'
Result — Object.prototype.polluted = "PWNED" process-wide. Observed in the webapp logs:
- The request's own query is corrupted —
polluted:"PWNED"injected into every object Prisma enumerates:prisma.taskRun.updateMany({ where:{ id:"…", metadataVersion:2, polluted:"PWNED" }, data:{ …, metadataVersion:{ increment:1, polluted:"PWNED" }, polluted:"PWNED" }, polluted:"PWNED" }) -> Unknown argument `polluted` - Cross-tenant authentication break — the next request from a different client (a worker's
POST /engine/v1/dev/dequeue) fails insidefindEnvironmentByApiKey:
i.e. one tenant's request breaks authentication for other tenants' workers → their jobs stop being dequeued/processed.prisma.runtimeEnvironment.findFirst({ where:{ apiKey:"…", polluted:"PWNED" }, include:{ project:true, …, polluted:"PWNED" } }) -> PrismaClientValidationError - Denial of service — full process crash. The
uncaughtExceptionin prom-client (`Error: Added…
- Record
GHSA-p28v-f755-9qrg- CVSS 3.1
- 8.5 High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:N/I:L/A:H - Weakness
- CWE-1321
- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
@trigger.dev/corenpm |
3.3.8 to 4.5.5 | 4.5.6 |
@trigger.dev/corenpm |
3.3.8 up to 4.5.6 | 4.5.6 |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-73654 is a high vulnerability (CVSS 8.5) in Triggerdotdev Trigger.dev, published August 13, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.62%, the 49th percentile. Fixed in @trigger.dev/core 4.5.6.
References
github.com/triggerdotdev/trigger.dev/security/advisories/GHSA-p28v-f755-9qrg
github.com/triggerdotdev/trigger.dev/pull/4316
github.com/triggerdotdev/trigger.dev/commit/6997aeb05e27d2db47f9eda01fdc8a17c81a1ae0
github.com/triggerdotdev/trigger.dev/releases/tag/v4.5.6
github.com/advisories/GHSA-p28v-f755-9qrg
github.com/CVEProject/cvelistV5/tree/main/cves/2026/73xxx/CVE-2026-73654.json
nvd.nist.gov/vuln/detail/CVE-2026-73654
github.com/triggerdotdev/trigger.dev
Left out here: the rest of 2 source descriptions. The JSON record has them.