Fix guide · medium · oauth_implicit_flow

OAuth uses implicit flow (response_type=token) — deprecated

What this rule means

Your authorize URL requests response_type=token. The OAuth 2.0 Security Best Current Practice (BCP) explicitly deprecates this — access tokens land in the URL fragment, where they leak via Referer headers, browser history, and analytics.

Why it matters

The implicit flow returns the access token directly to the browser as part of the redirect URL fragment (#access_token=...). It was originally designed for SPAs that couldn't securely store a client_secret — but it has well-documented leak channels:

Modern OAuth (RFC 8252, OAuth 2.1 draft) standardizes on authorization-code flow with PKCE for SPAs and mobile apps:

Every major OAuth provider (Google, GitHub, Microsoft, Auth0, Okta) supports PKCE. There is no scenario where implicit flow is the right choice for a new build.

How to fix it

Switch to authorization-code flow with PKCE:

  1. Change response_type=token to response_type=code in your authorize URL.
  2. Generate a PKCE code_verifier (random 43–128 char string) and its SHA-256 challenge:

``js const verifier = base64url(crypto.getRandomValues(new Uint8Array(32))); const challenge = base64url(await crypto.subtle.digest('SHA-256', new TextEncoder().encode(verifier))); ``

  1. Add code_challenge=<challenge>&code_challenge_method=S256 to the authorize URL.
  2. Store the verifier in sessionStorage (NOT localStorage — the latter persists across tabs).
  3. On callback, POST to the token endpoint with grant_type=authorization_code, the received code, and the original code_verifier.
  4. Use a battle-tested OAuth library: oauth4webapi (vanilla), @auth/core (Auth.js), react-oidc-context (React) — they handle PKCE correctly out of the box.

Don't roll this yourself. OAuth is one of those protocols where every state machine subtlety is the difference between secure and pwned.

Did vibecheck flag this on your app?

If you reached this page from a vibecheck inspection report, the redacted match in your scan output is the exact string we found in your bundle. After applying the fix above, run the inspection again — the finding should clear.

Run another inspection