Skip to content
stateless.co · Engineering notes from the request/response layer
statelessThe engineering desk

A publication about the machinery under everyday software: the contracts between services, the queries behind a page, and the failures that only show up in production.

05Security & Identity

Refresh Token Rotation and Reuse Detection: What the Attack Looks Like in Logs

You logged in and got a refresh token. You used it, and you got a new one. But now, after the interval between valid refresh-rotation windows, you try to use that first token again, as a…

Refresh Token Rotation and Reuse Detection: What the Attack Looks Like in Logs
Photo: Salisbury and South Wiltshire Museum, Katie Hinds, 2010-01-17 23:05:26 · CC BY-SA 4.0 · Wikimedia Commons
What is in this piece
  1. Rotation Basics
  2. Detecting Rotation and Reuse
  3. Revision Control
  4. Discordant Client
  5. Logging Advice
  6. Mitigation Matters

This is refresh token rotation and reuse detection, which needs source verification. For developers, there is a great risk to deploying this incorrectly or failing to monitor logs. An invalid log rotation can result in revoking all logged-in users' tokens on your authority.

Rotation Basics

A single refresh token is used, then discarded and replaced with a new token, issued with a new token for future use. This is a one-time use item, and failures to understand it lead to making the same token reusable, whether intentionally or by mistake. That means an attacker could reuse a token if rotation fails.

This history of rotation can be viewed as a family tree. One token begets another, in a one-to-one relationship, so long as the rotation takes effect. Any top-level credentials used against the authority will have a token and can be tracked to other operations through their family relationship. Repeated use of the same token, each for individual use, creates a token family.

Detecting Rotation and Reuse

When token rotation occurs, logs will show one token being used, then another. When the first token is used again, the system has to decide if that's an attack or whether some other issue occurred.

Where a token's possible use is tracked, access tokens will be associated with that refresh token, and attempts to use a token again will trigger rotation. If the token has been retired, the server must check if the used token was a rotation or reuse. This ambiguity mandates they must choose between automatically triggering rotation or declining the request, possibly even disrupting service.

Revision Control

When a token is used, the refresh tokens and access tokens it's associated with must be evaluated. Each authority manages this slightly differently, but a few things can be relied upon.

When the token is used, the authority will declare a family or lineage, which is the history of that token from original issuance. In the case of reuse, the whole family is revoked. Some may throw warning types, but the most typical outcome is revocation.

In addition to revoking the token family, the authority will also attempt to invalidate associated access tokens.

Discordant Client

There are a number of legitimate causes of reuse. When a refresh token is reused, it might be a retry. In the case of a network race, a returned token might fail to update its record. At that point, the server has no way to know if this is legitimate or an attack.

If an attacker has access to the token, ability to use access tokens they may try and brute-force or gain access with them. They may even just passively monitor the tokens as they change hands. This is one of the reasons rotation is considered security through minimum privilege: revoking credentials should revoke privilege.

Logging Advice

Rotation and reuse detection is a bit of a blur, as logs often do not make it clear what is happening. Logs should include the time of the event, the user ID, the IP address, and information about the token itself. By combining these logs, it's possible to see if a token has been reused.

Even with these logs, it remains difficult to know if you're being attacked or simply having a network race.

Mitigation Matters

What if the token is reused, and you need to ensure it can't be? The system should have a grace period to allow a legitimate client to retry. Ideally, this grace period would only last for a short time, such as 10-60 seconds. During this time, the token should remain valid for retry, ideally linked to this ID.

In addition, the system should be fault tolerant. This means it should not lock out a legitimate client if it uses a token again. It should also be able to detect when a token has been used multiple times in a short period and take appropriate action, such as requiring reauthorization.