GHSA-q567-cr4x-96w4
### Summary A WEBHOOK alert channel stores a user-supplied `url`. When an alert fires (deployment/run failure, error groups), the webapp server (`alertsWorker` -> `DeliverAlertService`) POSTs the HMAC-signed alert payload to that URL via `fetch(webhook.url, ...)`. The URL is never validated against a host allowlist or private-IP/metadata blocklist (a repo-wide search for `169.254`, `isPrivate`, `isLoopback`, `net.isIP`, `ssrf` returns ZERO hits), and the API route's URL field is just `z.string().optional()` (no syntax check at all). So an authenticated tenant can point the webhook at internal infrastructure or `169.254.169.254` and the multi-tenant server fetches it. ### Affected `apps/webapp`, HEAD `5d99457` (current main). ### Root cause - Source (API route): `app/presenters/v3/ApiAlertChannelPresenter.server.ts` `ApiAlertChannelData.url = z.string().optional()` (no host validation); route `app/routes/api.v1.projects.$projectRef.alertChannels.ts` (PAT-auth). - Store: `app/v3/services/alerts/createAlertChannel.server.ts` persists `{url, secret, version}` verbatim. - Sink: `app/v3/services/alerts/deliverAlert.server.ts:973` `fetch(webhook.url, {method:"POST", headers:{"x-trigger-signature-hmacsha256":...}, body:rawPayload})`; identical at `deliverErrorGroupAlert.server.ts:258`. Runs inside the webapp process; `fetch` follows redirects (IMDSv1-via-redirect). No egress guard anywhere. ### Runtime PoC (proven on self-host) Seeded a project + STAGING env + a WEBHOOK channel with `url=http://host.docker.internal:7766/...` (an internal address from the server's POV) + a DEPLOYING deployment. Triggered via the public API `POST /api/v1/deployments/deployment_ssrfpoc/fail` -> 200 -> FAILED -> alertsWorker -> the server fetched the listener. Captured: ``` POST /ssrf-via-webhook HTTP/1.1 host: host.docker.internal:7766 x-trigger-signature-hmacsha256: <redacted> user-agent: node {"type":"alert.deployment.failed", ...} ``` The webapp server (user-agent: node) made an outboun
Properties
- severity
- medium
- summary
- Trigger.dev: Blind SSRF via alert-channel webhook
- cvss_score
- 5.4
- retrieved_at
- 2026-10-03T18:15:00+00:00
- ghsa_published
- 2026-10-02T22:35:31Z
- source_url
- https://github.com/advisories/GHSA-q567-cr4x-96w4
- ghsa_updated
- 2026-10-02T22:35:32Z
- ghsa_id
- GHSA-q567-cr4x-96w4
- last_source
- GitHub Advisory Database
- cve_id
- GHSA-q567-cr4x-96w4
- cvss_vector
- CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N
- 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