OAUTH2_REFRESH_TOKEN_ROTATION_FAILURE security auth_error ai_generated true

OAuth2 refresh token rotation failure allows token theft

ID: security/oauth2-refresh-token-rotation-failure-allows-token-theft

Also available as: JSON · Markdown · 中文
87%Fix Rate
83%Confidence
1Evidence
2023-09-10First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
OAuth2.0 active
Spring Security 5.6+ active
Keycloak 21.0.0 active
Okta 2023.07.0 active

Root Cause

When refresh token rotation is not implemented, a stolen refresh token remains valid indefinitely, allowing an attacker to obtain new access tokens without detection.

generic

中文

当未实现刷新令牌轮换时,被盗的刷新令牌无限期有效,使攻击者能够获取新的访问令牌而不被发现。

Official Documentation

https://datatracker.ietf.org/doc/html/rfc6749#section-10.4

Workarounds

  1. 90% success Implement refresh token rotation: issue a new refresh token each time the old one is used, and invalidate the old token. Example in Spring Security: configure oauth2Client with refreshTokenRotationEnabled(true).
    Implement refresh token rotation: issue a new refresh token each time the old one is used, and invalidate the old token. Example in Spring Security: configure oauth2Client with refreshTokenRotationEnabled(true).
  2. 85% success Implement refresh token reuse detection: if a revoked refresh token is used, revoke all tokens for that user and alert. Example in Keycloak: enable 'Revoke Refresh Token' in client settings.
    Implement refresh token reuse detection: if a revoked refresh token is used, revoke all tokens for that user and alert. Example in Keycloak: enable 'Revoke Refresh Token' in client settings.
  3. 80% success Set a maximum refresh token lifetime (e.g., 24 hours) and force re-authentication after expiry, combined with rotation.
    Set a maximum refresh token lifetime (e.g., 24 hours) and force re-authentication after expiry, combined with rotation.

中文步骤

  1. Implement refresh token rotation: issue a new refresh token each time the old one is used, and invalidate the old token. Example in Spring Security: configure oauth2Client with refreshTokenRotationEnabled(true).
  2. Implement refresh token reuse detection: if a revoked refresh token is used, revoke all tokens for that user and alert. Example in Keycloak: enable 'Revoke Refresh Token' in client settings.
  3. Set a maximum refresh token lifetime (e.g., 24 hours) and force re-authentication after expiry, combined with rotation.

Dead Ends

Common approaches that don't work:

  1. 70% fail

    Setting a short access token lifetime (e.g., 5 minutes) does not protect against refresh token theft because the attacker can still use the refresh token to get new tokens repeatedly.

  2. 60% fail

    Revoking all tokens on logout is insufficient if the attacker already has the refresh token and uses it before logout.

  3. 50% fail

    Using a single refresh token with a long lifetime is the default in many OAuth2 implementations, which directly enables this vulnerability.