问题描述
用户认证流程中存在两个安全缺陷。
1. 验证码使用非加密安全的 PRNG
文件: backend/packages/app/src/windup_app/server/user/service.py:86-87
def _generate_code() -> str:
return "".join(random.choices(string.digits, k=6))
random.choices 使用 Mersenne Twister,不是密码学安全的随机数生成器。攻击者若能观察足够多的输出(或知道种子),可以预测后续验证码。
2. 刷新令牌轮换非原子
文件: backend/packages/app/src/windup_app/server/user/service.py:394-401
# 撤销旧 token
self.redis.delete(redis_key) # ← 第一步
# 签发新 token
new_access = create_access_token(...)
new_refresh, new_jti = create_refresh_token(...)
self._store_refresh_token(new_jti, user_id) # ← 第二步
两步之间存在竞态窗口:
- 服务崩溃 → 旧 token 已删、新 token 未存 → 用户被踢出
- 并发重试同一旧 token 可能在窗口内成功
建议修复
- 验证码:
import secrets,使用 secrets.choice(string.digits) 或 secrets.token_hex(3)。
- 令牌轮换: 使用 Redis
MULTI/EXEC 或 Lua 脚本原子执行"删除旧 token + 存储新 token"。
影响
- 严重程度: High
- 验证码可预测 → 账户接管
- Token 轮换竞态 → 用户意外登出或 token 复用
问题描述
用户认证流程中存在两个安全缺陷。
1. 验证码使用非加密安全的 PRNG
文件:
backend/packages/app/src/windup_app/server/user/service.py:86-87random.choices使用 Mersenne Twister,不是密码学安全的随机数生成器。攻击者若能观察足够多的输出(或知道种子),可以预测后续验证码。2. 刷新令牌轮换非原子
文件:
backend/packages/app/src/windup_app/server/user/service.py:394-401两步之间存在竞态窗口:
建议修复
import secrets,使用secrets.choice(string.digits)或secrets.token_hex(3)。MULTI/EXEC或 Lua 脚本原子执行"删除旧 token + 存储新 token"。影响