invalid_grant security auth_error ai_generated true

OAuth2 刷新令牌重放检测:相同的刷新令牌被多次使用

OAuth2 refresh token replay detected: same refresh token used more than once

ID: security/oauth2-token-replay-via-refresh-token

其他格式: JSON · Markdown 中文 · English
80%修复率
85%置信度
1证据数
2023-05-15首次发现

版本兼容性

版本状态引入弃用备注
OAuth 2.0 RFC 6749 active
Spring Security OAuth2 2.5.x active
Keycloak 21.0.x active
Auth0 Node.js SDK 2.0.0 active
Okta .NET SDK 3.0.0 active

根因分析

OAuth2 刷新令牌在每次使用后未轮换,导致窃取令牌的攻击者可以无限重放以获取新的访问令牌。

English

OAuth2 refresh token is not rotated after each use, allowing an attacker who steals the token to reuse it indefinitely and obtain new access tokens.

generic

官方文档

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

解决方案

  1. Implement refresh token rotation: issue a new refresh token with each access token refresh and invalidate the old one. Example: In Spring Security OAuth2, set `refreshTokenRotationEnabled=true` in authorization server config.
  2. Use refresh token expiration with a short TTL (e.g., 15 minutes) combined with rotation, and require re-authentication after expiry.
  3. Add a client-side nonce or binding to refresh token to tie it to a specific device or session, preventing cross-device replay.

无效尝试

常见但无效的做法:

  1. 95% 失败

    Longer expiration gives attackers more time to exploit stolen tokens; does not address the fundamental replay vulnerability.

  2. 70% 失败

    Blacklists are hard to maintain in distributed systems and require real-time synchronization; attackers can still replay before blacklisting.

  3. 85% 失败

    Rate limiting may block legitimate users and does not prevent a single replay attack; attacker can still use the token once before rate limit kicks in.