Refresh token abuse
A refresh token exists to let an app get new access tokens without bothering the user again. Stolen, it lets an attacker do the same thing indefinitely, surviving password resets along the way.
How it works
OAuth access tokens are deliberately short-lived, often valid for an hour or less, to limit the damage if one leaks. A refresh token is what makes that usable: it is a longer-lived credential the client presents to the identity provider to get a fresh access token without asking the user to sign in again. Refresh tokens are what device-code phishing, AITM proxies, and malicious OAuth consent grants are actually after, because a stolen access token expires quickly on its own, while a stolen refresh token keeps producing new ones for as long as it stays valid, which for many identity providers means weeks or months, renewed automatically every time it is used.
Once an attacker holds a refresh token, they run it through the same token endpoint the legitimate application uses, requesting new access tokens on their own schedule. The requests look like normal application behavior at the protocol level, because they are the same requests the real client makes.
Why it works
Refresh tokens exist specifically to reduce user friction, and reducing friction means reducing the number of checkpoints where a defender or the user could notice something wrong. A stolen refresh token requires no further interaction from the victim at all: no MFA prompt, no login screen, nothing for the user to see or approve, because the exchange happens entirely between the attacker's client and the token endpoint. Many implementations also do not bind the refresh token to the specific device or client that first received it, so it works identically wherever it is presented. A password reset addresses the credential that produced the original tokens, not the tokens already issued, so it frequently does nothing to stop ongoing refresh token use.
How to detect it
- Refresh token exchanges from an IP, client ID, or device that differs from the one the original grant was issued to.
- Token refresh activity continuing at a normal cadence after a password reset or account lockout, which indicates the reset did not reach the standing tokens.
- Access patterns that continue for weeks with no corresponding new interactive sign-in event in the logs.
Be honest about the limits: legitimate refresh token use from a new IP happens constantly, when a user travels, changes networks, or uses a mobile device with a rotating carrier address, so IP change alone is a weak signal. The stronger signal is refresh activity that survives a credential reset, since that is the behavior a legitimate client's tokens should not show.
How to stop it
- Revoke refresh tokens explicitly as part of password reset and incident response, not just the password itself; a reset that leaves tokens standing has not actually removed access.
- Shorten refresh token lifetimes and require re-authentication periodically rather than allowing indefinite silent renewal.
- Bind tokens to a device or client using DPoP so a copied refresh token fails when replayed from a different device.
- Rotate refresh tokens on every use and invalidate the entire family if an old, already-rotated token is presented again, which flags a replay attempt.
- Monitor OAuth application consents and grants for unfamiliar apps requesting offline access, since that scope is what produces a long-lived refresh token in the first place.
Seen in the wild
Sources
Related on Start with Identity
- TechniquePrimary Refresh Token theft
Code already running in a signed-in Windows session can drive the device's own Windows Hello key to obtain a Primary Refresh Token, no PIN prompt, no admin righ
- BlogA CVSS 10.0 bug let one user's Terraform token serve another user's request
HashiCorp's Terraform MCP Server failed to assign unique session identifiers in stateless HTTP mode, so a token supplied by one user could be reused for later r
- GlossaryAccess Token
A short-lived credential a client presents to a resource server to access protected data. Access tokens are typically opaque or JWT-formatted, with lifetimes me
- TechniqueAD CS certificate template abuse
A certificate template with permissive enrollment rights or a misconfigured extension turns Active Directory Certificate Services into a path to domain compromi
- CVECitrix Bleed, session-token leak from NetScaler ADC
A buffer over-read on NetScaler ADC/Gateway leaked session tokens in the clear. Attackers replayed them and skipped the login, including MFA. CISA KEV. October
- TechniqueCross-tenant token confusion
A broker sitting between users and a shared backend fails to keep sessions apart, so a token supplied by one caller gets used to serve a different caller's late