Średnia

Trigger.dev: Cross-environment deployment cancel

  • Ujawniono: 02.10.2026
  • Aktualizacja: 21.10.2026 14:17

Summary

Trigger.dev isolates each project into multiple environments (dev, staging, prod, and per-PR preview branches), each with its own secret API key — the environment is a trust boundary (a dev/preview/CI key is lower-trust than a prod key). Most API routes enforce this by scoping resource lookups to the authenticated key's environment (where: { friendlyId, runtimeEnvironmentId: auth.environment.id }).

The deployment cancel path does not. DeploymentService.getDeployment() scopes the lookup by projectId only — never environmentId — so a secret key for any environment in a project can cancel a deployment belonging to any other environment of the same project, including production. The deployment GET route, by contrast, is env-scoped — so the same key that is 404'd when trying to read a prod deployment can nonetheless cancel it. That asymmetry is the bug.

Affected

apps/webapp, HEAD 5d99457 (current main). Affects self-hosted and cloud.

Root cause

apps/webapp/app/routes/api.v1.deployments.$deploymentId.cancel.ts authenticates to an environment and calls deploymentService.cancelDeployment(authenticatedEnv, deploymentId, ...).

apps/webapp/app/v3/services/deployment.server.ts:

ts
public cancelDeployment(authenticatedEnv: Pick<AuthenticatedEnvironment,"projectId">, friendlyId, ...) {
  return this.getDeployment(authenticatedEnv.projectId, friendlyId)   // projectId only
    .andThen(validateDeployment)                                      // rejects only FINAL statuses
    .andThen(cancelDeployment);                                       // updateMany -> status CANCELED
}
private getDeployment(projectId: string, friendlyId: string) {
  return this._prisma.workerDeployment.findFirst({
    where: { friendlyId, projectId },        // <-- NO environmentId filter
  });
}

cancelDeployment accepts authenticatedEnv but its type is literally Pick<AuthenticatedEnvironment,"projectId"> — it discards the environment identity. validateDeployment blocks only FINAL_DEPLOYMENT_STATUSES, so any in-progress deployment (PENDING/INSTALLING/BUILDING/DEPLOYING) is cancellable.

Contrast — the correctly env-scoped sibling api.v1.deployments.$deploymentId.ts (GET):

ts
const deployment = await prisma.workerDeployment.findFirst({
  where: { friendlyId: deploymentId, environmentId: authenticatedEnv.id },   // env-scoped
});

Reads are env-scoped; the cancel mutation is not. The same getDeployment(authenticatedEnv.projectId, …) helper also backs the deployment progress methods (deployment.server.ts:172,329), so the projectId-only scope is a small class.

Runtime PoC (proven on the self-host stack)

Seeded one project with a prod env (key tr_prod_…) and a dev env (key tr_dev_…) and one WorkerDeployment (deployment_pocvictim, status DEPLOYING) in the prod env. As the dev key:

status BEFORE                                                  : DEPLOYING
GET  /api/v1/deployments/deployment_pocvictim   (dev key)      -> 404   (env-scoped read DENIES it)
POST /api/v1/deployments/deployment_pocvictim/cancel (dev key) -> 204
status AFTER                                                   : CANCELED   (prod deploy canceled by the dev key)
CONTROL: same cancel with a DIFFERENT project's key            -> 404   (projectId scope blocks cross-project)

The dev key cannot read the prod deployment (404) yet cancels it (204 → CANCELED); a different project's key is correctly 404'd — so the gap is precisely cross-environment within a project.

Czego dotyczy

Kliknij technologię, aby zobaczyć wszystkie dotyczące jej podatności.

PlatformaPaczkaPodatne wersjePoprawka w wersji
Paczka npm trigger.dev < 4.5.6 4.5.6

Odnośniki

Ocena CVSS 5.4/10
Wektor CVSS
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:L
Słabość (CWE)
CWE-639
Platforma
npm
Paczka
trigger.dev
Ujawniono
02.10.2026
Aktualizacja
21.10.2026 14:17

Źródła i licencje

OSV / GitHub Advisory Database - GHSA-4672-hwv6-gq62 - CC BY 4.0

Historia podatności: trigger.dev

Wszystkie opisane podatności tej paczki (Paczka npm), od najnowszej. Widać, czy to jednorazowa wpadka, czy paczka, której trzeba pilnować.

Wszystkie (10) w archiwum
Wszystkich wpisów
10
Pierwsza → ostatnia
10.2026 10.2026
Bez poprawki
0
Wykorzystywana w atakach
0

Rozkład istotności

  • Krytyczna 1
  • Wysoka 5
  • Średnia 4

Ujawnienia w latach

  1. 2026: 10
Istotność:
  1. Trigger.dev: Cross-environment deployment cancel ten wpis
    Średnia · 5.4 CVE-2026-114079 < 4.5.6 4.5.6
  2. Krytyczna CVE-2026-114088 < 4.5.4 4.5.4

Dowiedz się, które podatności dotyczą Twojej aplikacji

Po podłączeniu integracji DockRay i włączeniu raportowania oprogramowania DockRay porównuje zgłoszone wersje komponentów ze znanymi podatnościami i powiadamia o potwierdzonych dopasowaniach. Zakres zależy od obsługiwanej technologii i dostępnych biuletynów.

Podłącz swoją aplikację
Newsletter DockRay

Bezpieczeństwo aplikacji w Twojej skrzynce

Najważniejsze podatności, konkretne zalecenia i praktyczne wskazówki dla Twoich aplikacji. Wybierz technologie i śledź to, co ma znaczenie dla Twojego projektu.

  • Codzienne zestawienie nowych podatności, także krytycznych.
  • Powiadomienia o ważnych aktualizacjach.
  • Praktyczne porady o bezpieczeństwie i monitoringu aplikacji.

Pozostaw puste, aby otrzymywać informacje o wszystkich technologiach.

Zapis jest bezpłatny. Wypiszesz się jednym kliknięciem w wiadomości.