Node.js web应用每次菜单点击时校验用户认证状态的安全咨询
现有认证方案的安全性评估
你当前基于服务端session存储用户身份、每次请求校验req.session.username的逻辑是基础可行的认证方案,只要session数据存储在服务端,存储的username字段本身不会被前端篡改,能满足最基础的登录态校验需求,但仅靠这一层判断不足以完全保障应用安全,存在以下明显风险:
- 会话配置缺陷风险:如果你的session对应的Cookie没有开启
HttpOnly、Secure(HTTPS环境下)、SameSite属性,很容易出现XSS攻击窃取会话Cookie、HTTP传输被窃听截取会话ID、CSRF跨站请求伪造的问题,攻击者拿到合法会话ID后,就算你校验了req.session.username也会把攻击者的请求认作合法用户的请求 - 缺少会话有效性校验:仅判断username存在无法应对会话过期、用户主动登出后会话未完全销毁、账号被后台封禁的场景,这些场景下
req.session.username可能还存在,但实际用户已经没有访问权限 - 缺少细粒度权限校验:你仅校验了用户是否登录,没有校验当前登录用户是否拥有对应菜单项的访问权限,普通登录用户可能可以越权访问管理员专属的功能接口
- 会话固定攻击风险:如果登录前就给用户分配会话ID,攻击者可以构造固定的会话ID诱导用户登录,之后用同一个会话ID冒充用户访问,此时服务端也能查到
req.session.username而放行
补充的用户认证校验方式
分为前端请求前置校验和服务端补充校验两类:
前端请求前校验
注意:所有前端校验仅用于优化交互体验、减少无效请求,绝对不能作为安全判断的依据,所有安全校验逻辑必须在服务端实现
- 本地存储登录状态标记:用户登录成功后在
localStorage/sessionStorage里存储一个非敏感的登录标记(比如isLogin=1,不要存密码、完整用户信息),点击菜单项时先校验这个标记是否存在,不存在直接跳登录页,减少无效的服务端请求 - 前端路由守卫拦截:如果是单页应用,在路由跳转前先校验全局状态管理里(比如Vuex、Pinia、Redux)的登录状态,状态异常直接拦截跳转
- 校验本地凭证有效期:如果使用JWT类凭证方案,可以在前端先解析JWT的
exp字段判断是否过期,过期直接清本地状态跳登录
服务端补充校验(安全核心防线)
- 增加会话有效期校验:给session设置合理的过期时间,每次校验
req.session.username的同时校验会话是否在有效期内 - 增加CSRF Token校验:所有非GET的修改类请求都要携带CSRF Token,服务端校验通过才放行,防范跨站请求伪造
- 增加权限匹配校验:校验当前登录用户的角色/权限列表,和当前请求接口需要的权限是否匹配,避免越权访问
- 增加会话合法性校验:可以将用户的IP、UA等信息和会话绑定,当请求的IP/UA和会话绑定的信息不一致时,直接销毁会话要求用户重新登录,降低会话被劫持后的风险
- 敏感操作二次校验:涉及账号修改、资金操作等敏感接口,就算用户是登录状态,也要求用户输入二次验证信息(比如验证码、短信验证码、支付密码)才放行
内容的提问来源于stack exchange,提问作者Philomath
相关产品推荐
相关产品推荐

