fix(typeform): scope OAuth token postMessage to the app origin [AIS-298] - #11168
Merged
Conversation
Harika Kondur (harikakondur)
force-pushed
the
ais-298
branch
from
July 27, 2026 22:00
a320f8c to
0edcbe0
Compare
The Typeform OAuth landing page forwarded the freshly-minted access token to
`window.opener` with a `'*'` target origin, so the browser would deliver the
token regardless of what origin the opener had navigated to. The config screen
that receives it only checked `event.source`, not `event.origin`.
The callback is served from the same origin as the config screen that opened it
(the popup goes to `${window.location.origin}/callback` and the lambda redirects
back to `${origin}/frontend/`), so both sides can be pinned to that origin:
- send to the origin parsed from the callback URL instead of `'*'`
- ignore inbound messages whose origin is not our own
The origin is derived from the callback URL rather than read from
`window.location` directly to keep `processTokenCallback` injectable for tests,
and so one build works on prod, test and localhost alike.
Scoped to the Typeform app only; the other apps sharing this pattern (Slack,
Smartling, Jira, Optimizely) will be addressed in a follow-up PR.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Harika Kondur (harikakondur)
force-pushed
the
ais-298
branch
from
July 27, 2026 22:03
0edcbe0 to
173496b
Compare
Harika Kondur (harikakondur)
marked this pull request as ready for review
July 28, 2026 16:51
Copilot started reviewing on behalf of
Harika Kondur (harikakondur)
July 28, 2026 16:51
View session
Contributor
There was a problem hiding this comment.
Pull request overview
Goal
Narrow Typeform OAuth token handoff so the popup only postMessages to the app’s own origin and the config screen only accepts messages originating from that same origin, addressing AIS-298 (wildcard postMessage token leak).
Approach
- Sender (popup landing) derives
targetOriginfrom the callback URL’sorigininstead of using'*'. - Receiver (config screen) additionally validates
event.origin === window.location.origin(in addition to the existingevent.sourcecheck).
Scope
Typeform app frontend only; no dependency or infra changes.
Git commit proposal
fix(typeform): scope OAuth postMessage to app origin
Next steps
Run npx vitest run and ensure no other test files are affected by global time mocking.
Changes:
- Scope OAuth popup → opener
postMessagetarget origin to the callback URL origin. - Require
MessageEvent.originto matchwindow.location.originwhen receiving the token. - Add Vitest coverage for sender origin scoping behavior.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| apps/typeform/frontend/src/processTokenCallback.ts | Sends OAuth token/error to window.opener using a non-wildcard target origin derived from the callback URL. |
| apps/typeform/frontend/src/processTokenCallback.spec.ts | Adds tests asserting the sender never uses '*' and derives origin from the callback URL. |
| apps/typeform/frontend/src/Auth/TypeformOAuth.tsx | Verifies incoming token messages also match the current window origin. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Drop comments that restate the code they sit above and condense the postMessage rationale to the line that explains why the callback URL's origin is the correct target. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Tyler Pina (tylerpina)
approved these changes
Jul 29, 2026
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Purpose
The Typeform OAuth landing page forwarded the access token to
window.openerwith a'*'target origin, so the browser delivers it regardless of what origin the opener is on. The receiving config screen only checkedevent.source, notevent.origin.Approach
The callback is served from the same origin as the config screen that opened it, so both sides are pinned to that origin:
processTokenCallback.ts) — post to the origin parsed from the callback URL instead of'*'.Auth/TypeformOAuth.tsx) — also requireorigin === window.location.origin.Origin chain: the popup opens
`${window.location.origin}/callback`→ the lambda redirects to`${origin}/frontend/?token=...`on the same host.Target origin comes from the already-parsed callback URL rather than
window.location, keepingprocessTokenCallback(window)injectable for tests. Mirrors the AB Tasty fix inmarketplace-partner-apps(AIS-301).