# Trigger.dev: Run replay injects a task run into an attacker-chosen environment (cross-tenant write)

Trigger.dev replay action trusts client-supplied environmentId, letting any authenticated user inject task runs into another org's environment, consuming their queue and compute.

- Payout: Research
- Severity: high
- Program: Trigger.dev
- Found by: geo-chen
- Disclosed: 2026-10-02
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-qxpp-qjg8-x4jv
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-qxpp-qjg8-x4jv
- Tags: area:web domain:web impact:dos impact:integrity kind:research platform:ghsa sev:high tech:nodejs technique:source-review vuln:access-control vuln:business-logic vuln:idor

**Target:** Web dashboard replay endpoint /resources/taskruns/:runParam/replay
**Root cause:** The replay action member-scopes the source run but passes the target environmentId from the request body into findEnvironmentById, which filters by id only with no org/project membership check; TriggerTaskService then trusts the resolved environment.
**Steps:**
1. Authenticate as a user owning a run in your own org (runParam).
2. Obtain a target environment id (CUID) belonging to another org/project.
3. POST `/resources/taskruns/<own runParam>/replay` with body `environment=<victim env id>&failedRedirect=/...`.
4. Replay resolves victim environment via findFirst `WHERE id = $1` with no membership filter and calls TriggerTaskService against it, creating a run in the victim tenant.
**How found:** Source review: noticed the loader constrains the environment picker to the run's project but the action re-reads environmentId from the form and passes it to findEnvironmentById, which lacks a membership filter — a UI-gated-only control.
**Exploitation:** Attacker replays their own run with a victim environmentId; the unvalidated lookup returns the victim environment and TriggerTaskService creates a run there, consuming victim queue concurrency/compute and polluting run history. Requires knowing the target env id and a task identifier existing in the target env for execution.
**Insight:** When a form loader restricts a dropdown to allowed values, check whether the corresponding action re-validates the submitted value server-side; look for lookup helpers like findById that omit the membership join used elsewhere.

