Lab · 09 / 16
Catching a stolen token.
Access tokens are short-lived; refresh tokens keep you signed in. If one is copied, rotation turns the copy into an alarm.
- App
- the real app, holding tokens
- IdP
- issues and rotates tokens
- Attacker
- someone with a stolen refresh token
- POST /token · RT1
Step 1 of 6
The access token expired
In plain words Your day pass expired, so you show your season ticket to get a new one.
After 15 minutes the access token is no longer valid. The app sends refresh token RT1 to get a new one, without bothering the user.
POST https://idp.example.com/token grant_type=refresh_token &refresh_token=RT1 &client_id=web-app - AT2 + RT2
Step 2 of 6
New tokens, old one burned
In plain words You get a new pass and a new season ticket; the old one is torn up.
With rotation, every use returns a new refresh token (RT2) and RT1 becomes invalid. The IdP remembers that RT1 and RT2 belong to the same family.
- POST /token · RT1
Step 3 of 6
Someone replays the old token
In plain words Someone shows up with a photocopy of the torn-up season ticket.
RT1 had been stolen, for example from a log or a malicious browser extension. The attacker tries to use it to get fresh tokens.
- 400 invalid_grant
Step 4 of 6
Reuse detected: the family is revoked
In plain words The counter knows that ticket was already torn up, so it cancels every ticket in your name.
An already-used refresh token means two parties hold copies. The IdP cannot tell who is legitimate, so it revokes RT2 as well and can raise a security event.
- POST /token · RT2
Step 5 of 6
The real app tries next
In plain words You show your new season ticket, but it has been cancelled too.
When its access token expires again, the app presents RT2. It was revoked together with the whole family.
- 400 invalid_grant → login
Step 6 of 6
The user signs in again
In plain words You go back to the counter with your ID: a small hassle, but the thief is locked out.
The app sends the user back to the login page. One extra sign-in is the price; in exchange, a stolen refresh token stops working the moment it is used.
Flow complete.
Example domains and values. Nothing leaves your browser.