GHSA-qxpp-qjg8-x4jv
### Summary The 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. ### Details The 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: ```js const replayRunService = new ReplayTaskRunService(); const newRun = await replayRunService.call(taskRun, { environmentId: submission.value.environment, // attacker-controlled, unvalidated payload: submission.value.payload, ... }); ``` `submission.value.environment` comes from ReplayRunData (apps/webapp/app/v3/replayTask.ts: `environment: z.string().optional()`), so it is fully client-controlled. ReplayTaskRunService resolves it with no ownership check, apps/webapp/app/v3/services/replayTaskRun.server.ts:26-28: ```js const authenticatedEnvironment = await findEnvironmentById( overrideOptions.environmentId ?? existingTaskRun.runtimeEnvironmentId ); ``` findEnvironmentById, apps/webapp/app/models/runtimeEnvironment.server.ts:197-211: ```js export async function findEnvironmentById(id) { const environment = await $replica.runtimeEnvironment.findFirst({ where: { id }, // no membership / org / project filter include: authIncludeWithParent, }); if (!environment || environment.project.deletedAt !== null) return null; return toAuthenticated(environment); } ``` The reso
Properties
- summary
- Trigger.dev: Run replay injects a task run into an attacker-chosen environment (cross-tenant write)
- severity
- high
- cvss_score
- 7.1
- retrieved_at
- 2026-10-03T18:15:00+00:00
- ghsa_published
- 2026-10-02T19:31:17Z
- source_url
- https://github.com/advisories/GHSA-qxpp-qjg8-x4jv
- ghsa_updated
- 2026-10-02T19:31:17Z
- ghsa_id
- GHSA-qxpp-qjg8-x4jv
- last_source
- GitHub Advisory Database
- cve_id
- GHSA-qxpp-qjg8-x4jv
- cvss_vector
- CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:L
- signal_observed_at
- 2026-10-03T01:59:23+00:00
- is_ghsa_only
- true
Related Entities (4)
AFFECTS (1)
HAS_WEAKNESS (1)
REPORTED_BY (1)
VULNERABLE_TO (1)
Explore deeper with Ninja Signal's threat intelligence graph