从外部链接访问站点时Content Security Policy导致登录会话失效
问题成因分析&排查方向
高概率核心原因
你描述的「站内跳转/手动输入URL正常、第三方跳转/书签打开掉登录」的特征,高度匹配CSP自动升级非安全请求导致的cookie跨协议丢失场景:
- 如果你使用
helmet这类工具配置CSP,多数中间件默认会隐式开启upgrade-insecure-requests指令(你贴的配置没显式列不代表没生效),这个指令会把所有http请求自动升级为https发起 - 如果你的站点同时支持http/https、且session cookie没有设置
secure: true,也没有做跨协议的会话共享:- 站内跳转都是同协议,不会触发升级,cookie正常携带
- 手动输入URL时协议和站点一致,不会出问题
- 书签如果存的是http地址、第三方跳转来源是http站点时,请求被自动升级为https,http域名下种的session cookie无法被带到https请求中,后端就会判定为未登录
排查步骤
- 先打开浏览器控制台「安全」「控制台」标签,从第三方跳转/书签打开站点时,查看是否有CSP拦截报错、是否有请求被自动升级协议的提示
- 把CSP头临时换成
Content-Security-Policy-Report-Only(仅上报违规不实际拦截),验证是否还会出现掉登录的问题:- 如果不再掉登录,说明是CSP拦截了前端鉴权相关的资源,重点看控制台报的违规脚本/资源,确认是不是和登录状态判断相关的内联脚本没加正确的nonce被拦截
- 如果还是掉登录,进一步检查cookie配置,确认session cookie的
secure、SameSite属性是否和站点的协议、跳转场景匹配
- 检查你使用的CSP配置中间件的默认规则,确认是否隐式添加了
upgrade-insecure-requests、referrer等你没显式声明的指令:如果加了referrer no-referrer,且你的后端有请求referrer校验逻辑,第三方跳转/书签打开时referrer为空,也会触发后端清会话的逻辑 - 你当前配置中的nonce是固定值,不符合安全规范(nonce要求每次请求随机生成),固定值不仅起不到安全防护作用,还可能在部分场景下导致脚本校验失败被CSP拦截,建议先改成动态生成的随机值再测试
内容的提问来源于stack exchange,提问作者Rusty
相关产品推荐
相关产品推荐

