Skip to content

Delegated user-actor token capability checks are bypassed by the legacy alert-channel API.

Moderate
carderne published GHSA-wpjq-q67r-pg6m Aug 20, 2026

Software

trigger.dev

Affected versions

<= 4.5.11

Patched versions

>= 4.5.12

Description

Summary

api.v1.auth.user-actor-token.ts describes UATs as a strict downgrade of a PAT and accepts an optional cap. However, the legacy authenticateApiRequestWithPersonalAccessToken() helper accepts UATs and returns only { userId }, dropping the verified ability/cap. POST /api/v1/projects/:projectRef/alertChannels uses that helper and performs no UAT cap or ability check before calling CreateAlertChannelService.

A token capped to ["read:runs"] can therefore create a production webhook alert channel with attacker-controlled URL, secret, alert types, and environment types.

Impact

A holder of a delegated read-only UAT for a user in the target organization can modify project alert routing. With a webhook channel, this can route future deployment and error-group alerts to attacker-controlled infrastructure, creating project configuration integrity impact and potential confidentiality impact for future alert metadata.

Reproduction

I used a local, non-destructive harness that executes the real current source bodies for:

  • authenticateApiRequestWithPersonalAccessToken()
  • api.v1.projects.$projectRef.alertChannels.action()
  • CreateAlertChannelService.call()
  • CreateAlertChannelService.#createProperties()

Command:

timeout 120 node candidates/triggerdotdev_trigger_dev_uat-cap-alert-channel-write-bypass_2026-06-30/proof/trigger_uat_cap_alert_channel_harness.js

Observed:

  • UAT claims contain cap: ["read:runs"].
  • The simulated cap ability denies alert-channel writes.
  • The legacy helper returns only { userId: "attacker-user" }.
  • The route returns 200.
  • The service reaches projectAlertChannel.create() for a production webhook alert channel.

Severity

Moderate

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Network
Attack complexity
Low
Privileges required
Low
User interaction
None
Scope
Unchanged
Confidentiality
Low
Integrity
Low
Availability
None

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N

CVE ID

No known CVE

Weaknesses

No CWEs

Credits