# OAuth2 刷新令牌重用检测失败导致令牌被盗未被发现

- **ID:** `security/oauth2-refresh-token-reuse-detection-failure`
- **领域:** security
- **类别:** auth_error
- **验证级别:** ai_generated
- **修复率:** 87%

## 根因

授权服务器未实现刷新令牌轮换或重用检测，因此如果攻击者窃取刷新令牌并使用它，合法用户的令牌仍然有效，允许攻击者无限期地继续获取新的访问令牌。

## 版本兼容性

| 版本 | 状态 | 引入 | 弃用 |
|------|------|------|------|
| OAuth2 2.0 | active | — | — |
| Spring Security 6.2.0 | active | — | — |
| Keycloak 23.0.0 | active | — | — |
| Auth0 Node.js SDK 2.45.0 | active | — | — |

## 解决方案

1. ```
   实现刷新令牌轮换：每次使用刷新令牌时发放新的刷新令牌，并使旧的失效。在 Spring Security 中，在授权服务器配置中将 `refreshTokenRotationStrategy` 设置为 `ROTATE`。示例：`@Bean public OAuth2AuthorizationServerConfigurer authorizationServerConfigurer() { return new OAuth2AuthorizationServerConfigurer() .refreshTokenRotationStrategy(RefreshTokenRotationStrategy.ROTATE); }`。
   ```
2. ```
   实现刷新令牌重用检测：如果刷新令牌被多次使用，则撤销该客户端和用户的所有令牌。在 Keycloak 中，在客户端设置的“高级设置”下启用“撤销刷新令牌”。这将在重用时使令牌系列无效。
   ```
3. ```
   结合使用轮换和重用检测。将上次使用的刷新令牌存储在数据库中，并在每次请求时进行比较。如果令牌之前已被使用，则撤销所有令牌并提醒用户。示例伪代码：`if (token in usedTokens) { revokeAllTokens(user); alert("检测到安全漏洞"); } else { usedTokens.add(token); issueNewToken(); }`。
   ```

## 无效尝试

- **Set a very short expiration time for refresh tokens (e.g., 5 minutes)** — Short expiration reduces the window of opportunity but does not prevent reuse. An attacker can still use the token within that window, and the legitimate user's session is interrupted. (50% 失败率)
- **Use IP-based validation to detect unusual refresh token usage** — IP addresses can be spoofed or changed (e.g., via VPN), and legitimate users may have dynamic IPs, leading to false positives. This is not a reliable security measure. (60% 失败率)
- **Block the user account after a single refresh token use** — This would break legitimate usage where users refresh tokens normally. It also does not distinguish between the legitimate user and the attacker. (80% 失败率)
