Skip to content

fix(client): don't follow cross-origin redirects with a bearer token - #192

Merged
Bccorb merged 1 commit into
mainfrom
fix/no-bearer-on-cross-origin-redirect
Oct 18, 2026
Merged

Bccorb merged 1 commit into
mainfrom
fix/no-bearer-on-cross-origin-redirect

Conversation

@Bccorb

@Bccorb Bccorb commented Oct 18, 2026

Copy link
Copy Markdown
Contributor

Refs #177. Part of the v0.19 release (fells-code/seamless-auth-api#385).

What

In bearer transport, a request that carries a token (authorizedFetch and adapter calls):

  • asks fetch for redirect: 'manual' and follows a redirect itself only when the target is apiHost or a trustedOrigins entry, up to five hops, with fetch's method rules (303, or 301/302 after a POST, becomes a GET without a body)
  • rejects any other redirect with a new UntrustedRedirectError (exported from client, react and react-native) without sending the token on
  • rejects a browser's opaque manual redirect, whose target cannot be judged
  • where the platform follows redirects regardless (React Native's fetch), rejects a response that redirected to another origin. The token may already have gone on that platform, which is why the iOS check below matters
  • leaves a caller's explicit redirect alone, with the final-origin check still applied

Requests without a token and cookie transport are unchanged. Client minor changeset, since redirect-following behaviour changes.

Checks

  • npm run lint, npm run format:check, npm run typecheck: pass
  • npm test: 45 suites, 604 tests (Jest) and 41 (Vitest) pass, 8 new redirect cases
  • npm run build, npm run check-npm-build: pass
  • Real networking, Node 24 fetch against two local servers: a 302 to the other origin rejects with UntrustedRedirectError and that server received no request; a same-origin 302 is followed with Authorization kept

Not done (why this says Refs, not Closes)

#177's done-when also asks to verify iOS NSURLSession on a device or simulator against a 302 to another origin. That needs a React Native build; it is left open on the issue.

A token-bearing request asks fetch for redirect: 'manual', follows only
redirects to trusted origins itself, and rejects others with
UntrustedRedirectError. Where a platform follows anyway, a response that
ended on another origin is rejected.

Refs #177
@Bccorb
Bccorb merged commit 782583c into main Oct 18, 2026
5 checks passed
@Bccorb
Bccorb deleted the fix/no-bearer-on-cross-origin-redirect branch October 18, 2026 23:58
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.

1 participant