AUTH_RACE_002
security
runtime_error
ai_generated
partial
令牌撤销中的竞态条件允许重复使用过期令牌
Race condition in token revocation allows stale token reuse
ID: security/race-condition-in-token-revocation
78%修复率
82%置信度
1证据数
2024-01-10首次发现
版本兼容性
| 版本 | 状态 | 引入 | 弃用 | 备注 |
|---|---|---|---|---|
| JWT 0.12.0 | active | — | — | — |
| OAuth2 2.0 | active | — | — | — |
| Redis 7.2 | active | — | — | — |
根因分析
当令牌被撤销但并发请求在撤销完全提交到数据库之前验证它时,会发生竞态条件,允许重复使用过期令牌。
English
A race condition occurs when a token is revoked but a concurrent request validates it before the revocation is fully committed to the database, allowing stale token reuse.
官方文档
https://oauth.net/2/token-revocation/解决方案
-
Use a distributed lock (e.g., Redis Redlock) around the revocation and validation operations to ensure atomicity. Example in Node.js: const lock = await redisClient.acquireLock('token_revoke_lock', 5000); try { await revokeTokenInDB(tokenId); // Validation will now see the revoked state } finally { await lock.release(); } -
Implement a short blacklist (5-10 seconds) in memory (e.g., Guava Cache) for recently revoked tokens before checking the database, reducing the race window.
无效尝试
常见但无效的做法:
-
Use a simple cache like Memcached with a short TTL to store revoked tokens
85% 失败
Caching with TTL can expire before the revocation is processed, still allowing reuse; also, cache inconsistency across nodes worsens the race.
-
Add a small sleep() before validation after revocation
90% 失败
Sleeping is non-deterministic and doesn't guarantee atomicity; it also degrades performance.