Skip to content

fix: bump authkit-js to ^0.20.1 and harden returnTo redirects - #101

Merged
gjtorikian merged 2 commits into
mainfrom
devin/sec-1300-bump-authkit-js-harden-redirects
Jul 22, 2026
Merged

fix: bump authkit-js to ^0.20.1 and harden returnTo redirects#101
gjtorikian merged 2 commits into
mainfrom
devin/sec-1300-bump-authkit-js-harden-redirects

Conversation

@devin-ai-integration

Copy link
Copy Markdown
Contributor

Summary

Automated first-pass security fix for SEC-1300. Requires human security review before merge.

authkit-react exact-pinned @workos-inc/authkit-js to 0.20.0, freezing every consumer on a version with two confirmed defects that were fixed upstream in 0.20.1 (commit 138b602, PR #122):

  1. Logout-allowlist bypass → open redirect / javascript: XSS. In 0.20.0, signOut({ returnTo }) for a logged-out user (no access token in memory) calls window.location.assign(returnTo) on the raw, unvalidated value — bypassing the WorkOS logout-redirect allowlist that devs reasonably assume always validates returnTo.
  2. Auth-bootstrap DoS via malformed state. In 0.20.0, the callback handler does JSON.parse(stateParam) unguarded; a crafted link (?code=x&state=%7Bnot-json) throws, which — combined with the provider having no .catch() — permanently wedges the app on isLoading: true for that navigation.

Both were reproduced against the real 0.20.0 bundle and confirmed rejected on 0.20.1 (see Linear ticket for full attacker-perspective PoC).

Changes

  • package.json / lockfile:"@workos-inc/authkit-js": "0.20.0""^0.20.1". The caret both delivers the fixes and lets future patches flow instead of re-freezing consumers.

  • src/provider.tsx: add a .catch() to the createClient() promise so an init failure settles into an unauthenticated state instead of wedging isLoading: true (defense-in-depth for the DoS):

     }).then(async (client) => {
    ...
    setState((prev) => ({ ...prev, isLoading: false, user }));
    - });+ }).catch((error) => {+ console.error(error);+ setState((prev) => ({ ...prev, isLoading: false, user: null }));+ });
  • README.md: the onRedirectCallback example previously taught window.location.href = state.returnTo with no validation (seeding open-redirect/XSS into consumer apps). Now validates state.returnTo is same-origin before navigating, plus a security note that state is untrusted URL input.

Testing

  • npm run build — success.
  • npm run format:check — clean.
  • Reproduced the signOut open-redirect + javascript: XSS and the state DoS against the built 0.20.0 bundle (real browser + jsdom); verified 0.20.1 throws NoSessionError / treats malformed state as absent.

This is an automated first-pass fix; a human security reviewer should confirm before merge.

Link to Devin session: https://app.devin.ai/sessions/5de3ea20d3ad44aa81cb15e4b4da448a

Ship the upstream authkit-js 0.20.1 fixes to all consumers and remove two consumer-facing footguns.
- Bump @workos-inc/authkit-js from the exact pin 0.20.0 to ^0.20.1. The exact pin froze consumers on 0.20.0, which shipped an unvalidated signOut({ returnTo }) redirect for logged-out users (logout-allowlist bypass -> open redirect / javascript: XSS) and an unguarded JSON.parse of the callback state param (auth-bootstrap DoS on a crafted link). Both are fixed in 0.20.1; a caret range lets future patches flow.
- Add a .catch() to the provider's createClient() promise so an initialization failure can no longer wedge the app on isLoading:true.
- Harden the README onRedirectCallback example to validate state.returnTo against the app origin before navigating.
@devin-ai-integration

Copy link
Copy Markdown
ContributorAuthor
Original prompt from Linear User

Please work on ticket "authkit-react hard-pins authkit-js 0.20.0, shipping the known-fixed unvalidated signOut({ returnTo }) redirect (logout-allowlist bypass enabling XSS/open redirect) plus an auth-callback state parse DoS to all consumers" (SEC-1300)

@playbook:playbook-b588614117c7477a9b9729928385384f

@devin-ai-integration

Copy link
Copy Markdown
ContributorAuthor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@linear-code

Copy link
Copy Markdown

SEC-1300

@devin-ai-integrationdevin-ai-integrationBot changed the title Bump authkit-js to ^0.20.1 and harden returnTo redirectsfix: bump authkit-js to ^0.20.1 and harden returnTo redirectsJul 22, 2026
@greptile-apps

greptile-appsBot commented Jul 22, 2026

Copy link
Copy Markdown

Greptile Summary

This PR upgrades the authentication client and hardens initialization and redirect handling.

  • Upgrades @workos-inc/authkit-js from 0.20.0 to ^0.20.1.
  • Prevents superseded client initialization promises from updating provider state.
  • Settles initialization failures into an unauthenticated state.
  • Documents same-origin validation for callback redirects.

Confidence Score: 5/5

This looks safe to merge.

  • The cleanup guard covers both successful and failed stale initializations.
  • No blocking issue remains in the updated code.

Important Files Changed

FilenameOverview
src/provider.tsxGuards promise settlement after cleanup and handles client initialization failures.
package.jsonUpdates the authentication client dependency to the patched release range.
package-lock.jsonLocks the authentication client to version 0.20.1.
README.mdAdds same-origin redirect validation and warns that callback state is untrusted.

Reviews (2): Last reviewed commit: "fix: ignore stale createClient results a..." | Re-trigger Greptile

Comment threadsrc/provider.tsx
Guard the provider's createClient() then/catch handlers with a per-effect cancelled flag so a superseded initialization that settles late cannot clobber the current one's state (flagged in review).
@gjtorikian
gjtorikian merged commit 5481fa8 into mainJul 22, 2026
4 checks passed
@gjtorikian
gjtorikian deleted the devin/sec-1300-bump-authkit-js-harden-redirects branch July 22, 2026 20:57
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@gjtorikian