A refresh token with no expiry is a password that does not get rotated
The distinction between an access token and a refresh token is a design decision about convenience. The access token is short-lived so that a leak has a bounded effect. The refresh token exists so that the user does not have to sign in again, which means its lifetime determines how long a stolen credential remains useful. Configure that lifetime without a limit and the second mechanism cancels the first.
RFC 6749 defines both token types and leaves their lifetimes to the authorisation server. RFC 6819 discusses the consequences, including the fact that a refresh token is a long-lived credential that can be replayed to obtain new access tokens without further user interaction.
What the design gets wrong in practice
The failure is rarely a single setting. It is a combination of defaults that each seemed reasonable. The refresh token is issued without an expiry so that a mobile application does not log users out. The token is not bound to a device or a certificate so that it works from any client. The token is not rotated on use, so the same value stays valid for years. Revocation is available but nobody triggers it unless an account is formally disabled.
In that configuration, a token captured once is equivalent to the account password, with two differences that favour the attacker. Password changes do not necessarily invalidate it, because the token was issued before the change and the authorisation server may honour it until its own expiry. Multi-factor authentication does not apply to the refresh step, because the user already completed that check when the token was issued.
MITRE ATT&CK catalogues the technique as using an application access token. The important property is that the access is indistinguishable from legitimate application traffic, because it is legitimate application traffic.
Configuring the lifetime deliberately
The first decision is a maximum lifetime, expressed as an absolute value rather than an inactivity timeout. An inactivity timeout is useful, and an attacker who automates periodic use never triggers it. An absolute limit forces re-authentication on a schedule the defender controls.
The second decision is rotation. A refresh token that is replaced every time it is used limits the value of a captured token to the window before the legitimate client next refreshes, because reuse of the old value can be detected and the session terminated. Rotation only helps if reuse detection is implemented, and that detail is worth confirming rather than assuming.
The third decision is binding. Tying the token to a client certificate or a device identity means the token is not portable, which converts a leak from a remote opportunity into one that requires additional material.
The fourth decision concerns scope. A refresh token that carries every scope the user has is broader than any single application needs, and narrowing the granted scopes limits what a stolen token can reach.
Detection and response
The observable signals are behavioural. A token used from a source address the user has never used, a client that refreshes far more often than a UI would, or two clients using the same token concurrently are all patterns a monitoring system can surface against a baseline of normal application use.
On the response side, the useful action is targeted revocation of the token rather than a global account lock, because revocation can be scoped to the client identity and the affected session. The follow-up question is what the token could reach, which determines whether the investigation extends to mail, files or an administrative interface.
An inventory of issued refresh tokens by application makes this work routine. The question an owner needs to answer is which applications hold long-lived tokens for which accounts, and that list is the same list to review when a client is retired or a project ends. A token issued for a decommissioned integration is a credential with no owner, and it is the kind of credential that survives several organisational changes before anyone notices it.
Limitations
This article describes published specification guidance and configuration choices. It reports no incidents, no measurements and no experiments. Lifetime and rotation settings differ between authorisation servers, so the specific options should be confirmed in the documentation for the deployment in use.
References
- RFC 6749: The OAuth 2.0 Authorization Framework: https://www.rfc-editor.org/rfc/rfc6749
- RFC 6819: OAuth 2.0 Threat Model and Security Considerations: https://www.rfc-editor.org/rfc/rfc6819
- MITRE ATT&CK T1550.001: Use Alternate Authentication Material - Application Access Token: https://attack.mitre.org/techniques/T1550/001/
Top comments (0)