Skip to content

fix(typeform): scope OAuth token postMessage to the app origin [AIS-298] - #11168

Merged
Harika Kondur (harikakondur) merged 4 commits into
masterfrom
ais-298
Jul 29, 2026
Merged

fix(typeform): scope OAuth token postMessage to the app origin [AIS-298]#11168
Harika Kondur (harikakondur) merged 4 commits into
masterfrom
ais-298

Conversation

@harikakondur

@harikakondur Harika Kondur (harikakondur) commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Purpose

The Typeform OAuth landing page forwarded the access token to window.opener with a '*' target origin, so the browser delivers it regardless of what origin the opener is on. The receiving config screen only checked event.source, not event.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:

  • Sender (processTokenCallback.ts) — post to the origin parsed from the callback URL instead of '*'.
  • Receiver (Auth/TypeformOAuth.tsx) — also require origin === 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, keeping processTokenCallback(window) injectable for tests. Mirrors the AB Tasty fix in marketplace-partner-apps (AIS-301).

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>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 targetOrigin from the callback URL’s origin instead of using '*'.
  • Receiver (config screen) additionally validates event.origin === window.location.origin (in addition to the existing event.source check).

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 postMessage target origin to the callback URL origin.
  • Require MessageEvent.origin to match window.location.origin when 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.

Comment thread apps/typeform/frontend/src/processTokenCallback.ts Outdated
Comment thread apps/typeform/frontend/src/processTokenCallback.spec.ts
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>
@harikakondur
Harika Kondur (harikakondur) merged commit 980e4b6 into master Jul 29, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants