From 45b81bd4786d292c9081f7b56399e4a19576cb96 Mon Sep 17 00:00:00 2001 From: Junming Chen Date: Sun, 28 Dec 2025 23:56:05 -0500 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20authenticateUserOrA?= =?UTF-8?q?dmin=20=E8=AE=A4=E8=AF=81=E7=BB=95=E8=BF=87=E6=BC=8F=E6=B4=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加 username 和 loginTime 字段验证(与 authenticateAdmin 保持一致) - 无效/伪造会话自动删除并记录安全日志 - 删除未使用的 id 字段(死代码清理) 漏洞详情: - 位置:src/middleware/auth.js:1569-1581 - 原因:只检查 Object.keys(session).length > 0,未验证必须字段 - 影响:攻击者可通过注入最小会话 {foo:'bar'} 绕过认证 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/middleware/auth.js | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/middleware/auth.js b/src/middleware/auth.js index 44e3cb37..f051a266 100644 --- a/src/middleware/auth.js +++ b/src/middleware/auth.js @@ -1434,7 +1434,6 @@ const authenticateAdmin = async (req, res, next) => { // 设置管理员信息(只包含必要信息) req.admin = { - id: adminSession.adminId || 'admin', username: adminSession.username, sessionId: token, loginTime: adminSession.loginTime @@ -1567,17 +1566,25 @@ const authenticateUserOrAdmin = async (req, res, next) => { try { const adminSession = await redis.getSession(adminToken) if (adminSession && Object.keys(adminSession).length > 0) { - req.admin = { - id: adminSession.adminId || 'admin', - username: adminSession.username, - sessionId: adminToken, - loginTime: adminSession.loginTime - } - req.userType = 'admin' + // 🔒 安全修复:验证会话必须字段(与 authenticateAdmin 保持一致) + if (!adminSession.username || !adminSession.loginTime) { + logger.security( + `🔒 Corrupted admin session in authenticateUserOrAdmin from ${req.ip || 'unknown'} - missing required fields (username: ${!!adminSession.username}, loginTime: ${!!adminSession.loginTime})` + ) + await redis.deleteSession(adminToken) // 清理无效/伪造的会话 + // 不返回 401,继续尝试用户认证 + } else { + req.admin = { + username: adminSession.username, + sessionId: adminToken, + loginTime: adminSession.loginTime + } + req.userType = 'admin' - const authDuration = Date.now() - startTime - logger.security(`🔐 Admin authenticated: ${adminSession.username} in ${authDuration}ms`) - return next() + const authDuration = Date.now() - startTime + logger.security(`🔐 Admin authenticated: ${adminSession.username} in ${authDuration}ms`) + return next() + } } } catch (error) { logger.debug('Admin authentication failed, trying user authentication:', error.message)