[] fix(security): validate postMessage origins and fix slack middleware path - #11094
Conversation
Wiz Scan Summary
To detect these findings earlier in the dev lifecycle, try the Wiz Code extension for VS Code, JetBrains, or Visual Studio. |
773c013 to
fa631d2
Compare
64013ec to
da742b9
Compare
|
removed typeform changes which were fixed in this pr: #11168 |
33a4ac8 to
a6defb2
Compare
There was a problem hiding this comment.
Thanks for picking this up! The security intent is right, but the origin pinning lands on the wrong host for Jira + Slack and will break OAuth in prod. Requesting changes.
Pattern to mirror
#11168 (Typeform) already solved this class of bug the right way:
- Sender:
postMessage(data, origin)whereorigincomes from the callback page URL - Receiver:
event.origin === window.location.origin
Callback and opener share the app origin. The API/OAuth-redirect host is only a bounce — it is not event.origin on the message that carries the token.
Blocking
-
Jira receiver (
OAuth.tsx) —expectedOriginis derived fromOAUTH_REDIRECT_URI(https://api.jira.ctfapps.net). After token exchange the lambda 302s toFRONTEND_URL(https://app.jira.ctfapps.net), andstandaloneposts from there. Legitimate messages have originapp.jira…and get dropped.Fix: require
e.origin === window.location.origin(Typeform pattern). Update the specs to fireMessageEventwithhttps://app.jira.ctfapps.net, notapi..Note: the sender change in
standalone.ts(callback URLorigin) is already correct — leave it. -
Slack receiver (
useConnect.ts) — same mismatch.postMessageruns onhttps://slack.ctfapps.netafter the API HTML bounce; the listener requiresBACKEND_BASE_URLorigin (slack-api.ctfapps.net). Every successful OAuth message is rejected.Fix:
message.origin === window.location.origin. -
Slack + Smartling senders —
document.referrer ? … : window.location.originis the wrong target. Referrer can be the API bounce (Slack) or the IdP (Smartling SSO), sotargetOriginmay not match the opener. Even when referrer is stripped and the fallback works, Slack still dies on finding 2.Fix: use the callback page origin (Jira/Typeform style), not
document.referrer.
Suggested shape
| App | Sender targetOrigin |
Receiver check |
|---|---|---|
| Jira | callback origin ✅ already |
window.location.origin (not OAUTH_REDIRECT_URI) |
| Slack | callback origin (drop referrer) |
window.location.origin (not BACKEND_BASE_URL) |
| Smartling | callback origin (drop referrer) |
window.location.origin ✅ already |
Happy to pair on the Jira/Slack receiver bits if useful — once those two are flipped to app origin, the scary path is unblocked.
…path Senders (typeform, slack, smartling, jira standalone): replaced wildcard '*' with document.referrer-based origin so tokens are only sent to the known opener page. Receivers (typeform, slack, smartling, jira): added event.origin checks so fake postMessage injections from other pages are rejected. Slack lambda: changed 'api/tokens' to '/api/tokens' in the middleware mount array — the missing leading slash meant path-to-regexp@0.1.x never matched the route, silently bypassing request verification on POST /api/tokens. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
5022258 to
eda9cfd
Compare
Summary
Slack lambda — missing leading slash (APPS-1)
Wildcard postMessage — senders (APPS-2)
All four sender files replaced `'*'` with `document.referrer ? new URL(document.referrer).origin : window.location.origin`:
Wildcard postMessage — receivers (APPS-2)
Added `event.origin` checks to all receivers:
Test plan
🤖 Generated with Claude Code