{"id":"GHSA-qxpp-qjg8-x4jv","revision":null,"records":[{"revision":"944f6e81c5154798ba4aa5cfde168f7f","observedAt":"2026-10-23T15:48:27.903+00:00","statement":{"source":"cve-program","id":"CVE-2026-85651","aliases":[],"title":"Trigger.dev before 4.5.2 Unauthorized Environment Access via Run Replay","description":"Trigger.dev versions before 4.5.2 fail to validate environment membership during run replay operations, allowing authenticated attackers to inject task runs into arbitrary environments. Attackers can replay their own runs into other organizations' or projects' environments to consume victim resources and pollute run history.","state":0,"publishedAt":"2026-09-04T14:32:17.468+00:00","modifiedAt":"2026-09-10T15:08:30.643+00:00","affected":[{"ecosystem":"Vendor product","name":"trigger.dev","ranges":[],"versions":[],"rawVersionEvidence":"{\n                    \"vendor\": \"triggerdotdev\",\n                    \"product\": \"trigger.dev\",\n                    \"defaultStatus\": \"unaffected\",\n                    \"versions\": [\n                        {\n                            \"version\": \"0\",\n                            \"lessThan\": \"4.5.2\",\n                            \"status\": \"affected\",\n                            \"versionType\": \"semver\"\n                        }\n                    ]\n                }"}],"metrics":[{"system":"CVSS 4.0","vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:H/VA:L/SC:N/SI:H/SA:L","score":8.4,"severity":"HIGH"},{"system":"CVSS 3.1","vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:N/I:H/A:L","score":8.5,"severity":"HIGH"}],"references":["https://github.com/triggerdotdev/trigger.dev/issues/4173","https://github.com/triggerdotdev/trigger.dev","https://github.com/triggerdotdev/trigger.dev/commit/34b1a181c2a1d33a53ebab88f84b05f81fea4254","https://github.com/triggerdotdev/trigger.dev/releases/tag/v4.5.2","https://github.com/triggerdotdev/trigger.dev/security/advisories/GHSA-qxpp-qjg8-x4jv","https://www.vulncheck.com/advisories/trigger-dev-before-4.5.2-unauthorized-environment-access-via-run-replay"],"sourceUrl":"https://www.cve.org/CVERecord?id=CVE-2026-85651","license":"CVE Program Terms of Use","key":"cve-program:CVE-2026-85651","identifiers":["CVE-2026-85651"]},"retained":false,"historicalAffected":[]},{"revision":"d1dbbbd717b04d50970301d69709fe93","observedAt":"2026-11-11T17:01:54.612+00:00","statement":{"source":"euvd","id":"EUVD-2026-71115","aliases":["CVE-2026-85651","GHSA-r87q-rjwf-c49g"],"title":"Trigger.dev versions before 4.5.2 fail to validate environment membership during run replay operations, allowing authenticated attackers to inject task runs into arbitrary environments. Attackers can replay their own runs into other organiz…","description":"Trigger.dev versions before 4.5.2 fail to validate environment membership during run replay operations, allowing authenticated attackers to inject task runs into arbitrary environments. Attackers can replay their own runs into other organizations' or projects' environments to consume victim resources and pollute run history.","state":0,"publishedAt":null,"modifiedAt":null,"affected":[],"metrics":[{"system":"EUVD CVSS 4.0","vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:H/VA:L/SC:N/SI:H/SA:L","score":8.4,"severity":null}],"references":["https://github.com/triggerdotdev/trigger.dev/issues/4173","https://github.com/triggerdotdev/trigger.dev","https://github.com/triggerdotdev/trigger.dev/commit/34b1a181c2a1d33a53ebab88f84b05f81fea4254","https://github.com/triggerdotdev/trigger.dev/releases/tag/v4.5.2","https://github.com/triggerdotdev/trigger.dev/security/advisories/GHSA-qxpp-qjg8-x4jv","https://www.vulncheck.com/advisories/trigger-dev-before-4.5.2-unauthorized-environment-access-via-run-replay"],"sourceUrl":"https://euvd.enisa.europa.eu/vulnerability/EUVD-2026-71115","license":"ENISA EUVD · source terms and attribution apply","enrichment":{"sourceStatus":null,"weaknesses":[],"productCriteria":[],"sourceDates":{"datePublished":"Sep 4, 2026, 2:32:17 PM","dateUpdated":"Sep 10, 2026, 3:08:30 PM"},"relatedAdvisories":[],"note":"EUVD source date text has no stated timezone and is retained without inventing a UTC instant. Related bulletin membership is not an alias, common cause or applicability claim. A missing vector with a zero score is treated as unrated. Complete vendor/product and underlying source evidence remains in the original JSON."},"key":"euvd:EUVD-2026-71115","identifiers":["EUVD-2026-71115","CVE-2026-85651","GHSA-r87q-rjwf-c49g"]},"retained":false,"historicalAffected":[]},{"revision":"d637f6892ace4361abcc0390b64577e4","observedAt":"2026-10-25T16:19:16.24+00:00","statement":{"source":"nvd","id":"CVE-2026-85651","aliases":[],"title":"Trigger.dev versions before 4.5.2 fail to validate environment membership during run replay operations, allowing authenticated attackers to inject task runs into arbitrary environments. Attackers can replay their own runs into other organiz…","description":"Trigger.dev versions before 4.5.2 fail to validate environment membership during run replay operations, allowing authenticated attackers to inject task runs into arbitrary environments. Attackers can replay their own runs into other organizations' or projects' environments to consume victim resources and pollute run history.","state":0,"publishedAt":"2026-09-04T15:17:43.347+00:00","modifiedAt":"2026-09-23T17:17:43.317+00:00","affected":[],"metrics":[{"system":"CVSS 4.0 · disclosure@vulncheck.com · Secondary","vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:H/VA:L/SC:N/SI:H/SA:L/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X","score":8.4,"severity":"HIGH"},{"system":"CVSS 3.1 · disclosure@vulncheck.com · Secondary","vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:N/I:H/A:L","score":8.5,"severity":"HIGH"}],"references":["https://github.com/triggerdotdev/trigger.dev","https://github.com/triggerdotdev/trigger.dev/commit/34b1a181c2a1d33a53ebab88f84b05f81fea4254","https://github.com/triggerdotdev/trigger.dev/issues/4173","https://github.com/triggerdotdev/trigger.dev/releases/tag/v4.5.2","https://github.com/triggerdotdev/trigger.dev/security/advisories/GHSA-qxpp-qjg8-x4jv","https://www.vulncheck.com/advisories/trigger-dev-before-4.5.2-unauthorized-environment-access-via-run-replay"],"sourceUrl":"https://nvd.nist.gov/vuln/detail/CVE-2026-85651","license":"NIST NVD usage terms; underlying source attribution retained","enrichment":{"sourceStatus":"Deferred","weaknesses":["CWE-862"],"productCriteria":[],"sourceDates":{"published":"2026-09-04T15:17:43.347","lastModified":"2026-09-23T17:17:43.317"},"relatedAdvisories":[],"note":"NVD analysis and CPE criteria are source context, not proof that a package or your environment is affected. Complete affected data, logical configurations and SSVC are retained in the original JSON."},"key":"nvd:CVE-2026-85651","identifiers":["CVE-2026-85651"]},"retained":false,"historicalAffected":[]},{"revision":"f01b1b3228db4648b44a4c419a0631e5","observedAt":"2026-10-24T13:17:17.793+00:00","statement":{"source":"osv","id":"GHSA-qxpp-qjg8-x4jv","aliases":["CVE-2026-85651"],"title":"Trigger.dev: Run replay injects a task run into an attacker-chosen environment (cross-tenant write)","description":"### Summary\nThe dashboard replay action authorizes the source run (it must belong to the caller's org), but the target environment for the replayed run is taken verbatim from the request body and is never checked for org or project membership. The environment lookup used by the replay path filters by id only. As a result, an authenticated user can replay one of their own runs into another organization's or project's environment, creating a task run there that consumes the victim tenant's queue and compute and pollutes their run history.\n\n### Details\nThe replay action member-scopes the source run correctly (apps/webapp/app/routes/resources.taskruns.$runParam.replay.ts, the findFirst on taskRun filtered by `project.organization.members.some.userId`), but passes the target environment straight from the submitted form, resources.taskruns.$runParam.replay.ts:344-346:\n```js\nconst replayRunService = new ReplayTaskRunService();\nconst newRun = await replayRunService.call(taskRun, {\n  environmentId: submission.value.environment,   // attacker-controlled, unvalidated\n  payload: submission.value.payload,\n  ...\n});\n```\n`submission.value.environment` comes from ReplayRunData (apps/webapp/app/v3/replayTask.ts: `environment: z.string().optional()`), so it is fully client-controlled.\n\nReplayTaskRunService resolves it with no ownership check, apps/webapp/app/v3/services/replayTaskRun.server.ts:26-28:\n```js\nconst authenticatedEnvironment = await findEnvironmentById(\n  overrideOptions.environmentId ?? existingTaskRun.runtimeEnvironmentId\n);\n```\nfindEnvironmentById, apps/webapp/app/models/runtimeEnvironment.server.ts:197-211:\n```js\nexport async function findEnvironmentById(id) {\n  const environment = await $replica.runtimeEnvironment.findFirst({\n    where: { id },                 // no membership / org / project filter\n    include: authIncludeWithParent,\n  });\n  if (!environment || environment.project.deletedAt !== null) return null;\n  return toAuthenticated(environment);\n}\n```\nThe resolved environment is then handed to TriggerTaskService.call (apps/webapp/app/v3/services/triggerTask.server.ts), which trusts the passed authenticatedEnvironment and performs no further authorization. The replay loader does constrain the environment picker to the run's own project (replay.ts around 178-184), but the action does not re-impose that constraint, so the server-side control is missing (UI-gated only).\n\n### PoC\nAs an authenticated user who owns a run in their own org (run param runParam), and who knows a target environment id belonging to another org or project (a CUID, obtained or guessed):\n```http\nPOST /resources/taskruns/<own runParam>/replay\nContent-Type: application/x-www-form-urlencoded\n\nenvironment=<environment id of the victim org/project>&failedRedirect=/...\n```\nThe replay resolves the victim environment with no membership check and calls TriggerTaskService against it, creating a run in the victim tenant.\n\nLive-validated: a Postgres database was seeded with two tenants (orgA with env_A, orgB with env_B_victim) and the verbatim findEnvironmentById lookup (findFirst joining the environment to its project, `WHERE id = $1`, the exact query the replay path runs) was executed with the victim env id as an orgA attacker. Captured:\n```\n[002 replay findEnvironmentById] attacker(orgA) supplied env_B_victim -> {\"id\":\"env_B_victim\",\"organization_id\":\"orgB\",\"project_id\":\"proj_B\",\"deleted_at\":null}\nCROSS-TENANT: CONFIRMED (resolved another org's env with no membership check -> replay would run there)\n```\nThe lookup returned another organization's environment with no membership filter. That the replay action passes the client-supplied environmentId straight into this lookup (and TriggerTaskService trusts the returned env) is verified at source.\n\n### Impact\nAn authenticated user can create task runs in another tenant's environment (including production), consuming that tenant's queue concurrency and compute and inserting entries into their run history. Practical exploitation requires knowing a target environment id (not enumerable) and, for the injected run to actually execute rather than error, a task identifier that exists in the target environment; this bounds reliability but not the unauthorized cross-tenant write itself.\n\n### Remediation\nIn the replay action (or in ReplayTaskRunService), require the resolved target environment to belong to the source run's project/organization, for example assert `environment.projectId === existingTaskRun.projectId`, or re-validate the supplied environment id against the caller's membership (findEnvironmentBySlug with the validated projectId, or a members.some.userId filter), mirroring the constraint the loader already applies to the picker.","state":0,"publishedAt":"2026-10-02T19:31:17+00:00","modifiedAt":"2026-10-02T19:45:03.5133038+00:00","affected":[{"ecosystem":"npm","name":"trigger.dev","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"0"},{"kind":"fixed","version":"4.5.2"}]}],"versions":[],"rawVersionEvidence":null}],"metrics":[{"system":"CVSS_V3","vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:L","score":null,"severity":null},{"system":"Publisher rating","vector":null,"score":null,"severity":"HIGH"}],"references":["https://github.com/triggerdotdev/trigger.dev/security/advisories/GHSA-qxpp-qjg8-x4jv","https://github.com/triggerdotdev/trigger.dev/pull/4199","https://github.com/triggerdotdev/trigger.dev/commit/34b1a181c2a1d33a53ebab88f84b05f81fea4254","https://github.com/triggerdotdev/trigger.dev","https://github.com/triggerdotdev/trigger.dev/releases/tag/v4.5.2"],"sourceUrl":"https://github.com/advisories/GHSA-qxpp-qjg8-x4jv","license":"GitHub Advisory Database · CC-BY-4.0","key":"osv:GHSA-qxpp-qjg8-x4jv","identifiers":["GHSA-qxpp-qjg8-x4jv","CVE-2026-85651"]},"retained":false,"historicalAffected":[]}],"coverage":[{"source":"cisa-kev:global","scope":"Complete CISA KEV catalog; all vendors. Missing entries do not establish absence of exploitation.","generation":"2026-11-11T19:58:45.4661486+00:00","complete":true,"records":1779,"lastAttemptAt":"2026-11-11T19:58:45.4661486+00:00","lastSuccessAt":"2026-11-11T19:58:45.6262555+00:00","error":null,"lastVerifiedAt":"2026-11-11T19:58:45.6262565+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"cve-program","scope":"Official CVE Program baseline and cumulative hourly delta; all vendors, published and rejected records","generation":"cve-de3b77103708811b6494d2ff7c979037d73ae579742cd1649a5c765137ae5083-bc2564cf749a574ebe6216cd53b2772c98ccf01e107d9e465c7cb9637c59db40","complete":true,"records":424281,"lastAttemptAt":"2026-11-11T19:56:48.005675+00:00","lastSuccessAt":"2026-11-11T19:56:47.8167322+00:00","error":null,"lastVerifiedAt":"2026-11-11T19:56:48.005675+00:00","snapshotPublishedAt":"2026-11-11T19:18:45+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"euvd","scope":"Rolling EUVD lookups of CVE aliases in current public OSV archives; 500 identifiers per refresh, rechecked after 48 hours. Not a global EUVD catalog. Successful not-found lookups count as checked; they do not imply withdrawal or safety. No reader inventory is sent.","generation":"enrichment-82ac7de7199b4b14afc134d5851bc951","complete":false,"records":13759,"lastAttemptAt":"2026-11-11T20:02:25.0308843+00:00","lastSuccessAt":"2026-11-11T20:02:25.1648436+00:00","error":null,"lastVerifiedAt":"2026-11-11T20:02:25.1648436+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"first-epss:nuget","scope":"FIRST EPSS for explicit CVE aliases in the collected public NuGet archive. Not a global EPSS backfill.","generation":"2026-11-11T19:58:45.4661486+00:00","complete":true,"records":1097,"lastAttemptAt":"2026-11-11T19:58:45.4661486+00:00","lastSuccessAt":"2026-11-11T19:58:45.6274866+00:00","error":null,"lastVerifiedAt":"2026-11-11T19:58:45.6274869+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"nvd","scope":"Rolling NVD lookups of CVE aliases in current public OSV archives; 500 identifiers per refresh, rechecked after 48 hours. Not a global NVD catalog. Successful not-found lookups count as checked; they do not imply withdrawal or safety. No reader inventory is sent.","generation":"enrichment-0feae4fee9a0467f9dde710515b6c624","complete":false,"records":13753,"lastAttemptAt":"2026-11-11T19:59:11.1509472+00:00","lastSuccessAt":"2026-11-11T19:59:11.147+00:00","error":"100 identifier lookups failed; latest failures include request timeout. Other identifiers were checked independently.","lastVerifiedAt":"2026-11-11T19:59:11.147+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":13713,"expectedIdentifiers":13813,"failedIdentifiers":100},{"source":"osv:Go","scope":"Complete OSV Go ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"go-3562b6c78fd1bd0f0b55daf66a0926ae24f65e462df7f6d928caad458fc696bf","complete":true,"records":9947,"lastAttemptAt":"2026-11-11T19:58:45.3029621+00:00","lastSuccessAt":"2026-11-11T04:27:43.6877707+00:00","error":null,"lastVerifiedAt":"2026-11-11T19:58:45.3029621+00:00","snapshotPublishedAt":"2026-11-11T03:32:46+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:NuGet","scope":"Complete OSV NuGet ecosystem archive, including GitHub Advisory Database records; NuGet version matching only","generation":"nuget-456002455e0ab94bb92c95476d4e6d175c104cd594749982afd96c893728ecbc","complete":true,"records":2010,"lastAttemptAt":"2026-11-11T19:56:48.0811645+00:00","lastSuccessAt":"2026-11-11T02:36:58.1276999+00:00","error":null,"lastVerifiedAt":"2026-11-11T19:56:48.0811645+00:00","snapshotPublishedAt":"2026-11-11T01:17:51+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:crates.io","scope":"Complete OSV crates.io ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"crates.io-baa8362b4daf9e5f39d5563775a55935e7b442c0735d33274a921579ce4a0d66","complete":true,"records":3093,"lastAttemptAt":"2026-11-11T19:58:45.4258391+00:00","lastSuccessAt":"2026-11-11T13:00:02.5446881+00:00","error":null,"lastVerifiedAt":"2026-11-11T19:58:45.4258391+00:00","snapshotPublishedAt":"2026-11-11T12:47:47+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:npm","scope":"Complete OSV npm ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"npm-87231cdc7f9d4c655d3fcacbfa9f6f611f1797a1979bf49bac181b1f6e58d128","complete":true,"records":231686,"lastAttemptAt":"2026-11-11T19:58:45.1608584+00:00","lastSuccessAt":"2026-11-11T19:58:43.6336294+00:00","error":null,"lastVerifiedAt":"2026-11-11T19:58:45.1608584+00:00","snapshotPublishedAt":"2026-11-11T19:48:16+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null}]}