复查修复(四): 独立审查发现的问题

- S1/S2: 会话锁改 RLock(持锁可重入调 _save_sessions);cookie 时间戳改整数+解析兼容(会话创建/验证往返已实测)
- M1: api_login 接入 verify_user(账号锁定/失败计数生效),DB 无用户时才回退 config 凭据
- M3+L5: handler _do_auth 统一入口加 IP 白名单检查;未知 auth_type 返回 401
- M4+L10: metrics 与无版本 /api/admin/ 加入受保护端点
- M6: debug 日志敏感头脱敏;main.py 不再打印 token 前缀
- M7: auth_token.txt / auth_sessions.json chmod 600
- M9: verify_user 统一错误消息防用户枚举
- M10: AdminAPI 复用共享 APIAuthManager(修复会话状态分裂)
- L7: check_auth 大小写不敏感匹配(防 /API/.. 大写绕过)
- L8: token_expires_at 显式 is not None 判断
- L11: verify_password 对非 bcrypt 哈希回退 PBKDF2(重写,修复 ValueError 分支不落回退的问题)
This commit is contained in:
HYC Fixer
2026-09-02 00:45:01 +08:00
parent f77a51247c
commit abdbec85a4
7 changed files with 807 additions and 754 deletions
+5 -1
View File
@@ -16,7 +16,11 @@ class AdminAPI:
def __init__(self, config: dict):
self.config = config
self.auth_manager = APIAuthManager(config)
# 复用共享认证管理器(router 注入的 config['_auth_manager']),
# 避免多实例各自持有会话表导致状态分裂
self.auth_manager = config.get('_auth_manager') or APIAuthManager(config)
if config.get('_auth_manager') is None:
config['_auth_manager'] = self.auth_manager
def handle_request(self, handler, method, path, query_params):
"""处理管理员API请求"""
+14 -5
View File
@@ -3315,11 +3315,12 @@ class APIv2(APIv1):
config_user = config.get('auth_user', '')
config_pass = config.get('auth_pass', '')
# 数据库验证
if db:
user = db.get_user_with_password(username)
if user and db.verify_password(password, user['password_hash']):
# 数据库验证成功,生成 token
# 数据库验证(走 verify_user: 含账号锁定/失败计数/启用检查)
if db and db.get_user(username):
result = db.verify_user(username, password)
if result.get('valid'):
user = result['user']
# 验证成功,生成 token
import secrets
token = secrets.token_hex(32)
token_expires_at = time.time() + 86400 # 24小时过期
@@ -3337,6 +3338,14 @@ class APIv2(APIv1):
"level": user.get('role', 'admin')
})
return
else:
# 账号锁定/禁用/密码错误:记录失败并返回,不回退到 config 凭据
db.add_login_log(username, client_ip, 'failed', result.get('reason', '验证失败'))
handler.send_json_response({
"success": False,
"error": result.get('reason', '用户名或密码错误')
}, 401)
return
# 配置文件验证(仅当数据库中没有该用户时)
if username == config_user and password == config_pass: