第77篇AI全栈·由CSRF引起的对常用鉴权方式总结

admin 2026-09-13 04:38:05 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文从CSRF漏洞案例切入,系统对比Cookie、Session与Token/JWT等鉴权方式的原理、攻击面与适用场景。核心结论是CSRF攻击面与凭证存储位置直接相关:凭证在Cookie中风险高,在Header中则CSRF基本不适用但引入XSS与CORS风险。建议开发侧对敏感操作增加二次验证并设置SameSite属性,测试侧先确认凭证位置再决定测试优先级。 综合评分: 88 文章分类: WEB安全,漏洞分析,安全意识,安全工具


第77篇 AI全栈 · 由CSRF引起的对常用鉴权方式总结

原创

陈看山 陈看山

安全诸子

2026年9月12日 13:40 上海

在小说阅读器读本章

去阅读

在公众号小说中沉浸阅读

在测试一个后台管理系统时,我习惯性地先抓包看接口的鉴权方式。密码修改接口没有验证旧密码,这几乎是CSRF的教科书式漏洞场景。但当我准备构造PoC时,发现该接口的身份凭证并非放在Cookie中,而是放在请求头里的自定义Token字段。Cookie是浏览器自动携带的,而Header里的Token则需要JavaScript手动添加。这意味着即便受害者点击了恶意链接,跨域请求也无法自动带上这个Token,攻击自然无法成立。 这个案例引出了一个在安全测试和前后端联调中反复出现的问题:Cookie、Session、Token,这些鉴权方式到底有什么区别?它们的失效场景和攻击面分别是什么?把这个问题理清楚,比单纯记住某个漏洞的利用条件更有价值。

CSRF的核心前提

浏览器自动携带凭证 CSRF(跨站请求伪造)之所以能成立,依赖的是浏览器的自动行为。当用户登录了某个网站A,浏览器会保存A站下发的Cookie。此时用户访问了恶意网站B,B页面中隐藏的请求指向A站,浏览器在发出这个请求时,会无条件自动附带A站的Cookie。服务器端如果仅靠Cookie中的Session ID来识别用户身份,就会把这个伪造请求当成合法操作。 关键点在于:Cookie的自动携带是浏览器的默认机制,不受页面来源限制。只要请求目标是A站域名,浏览器就会附加该域名下的Cookie,这与请求是从哪个页面发出的无关。 现在回到开头那个案例。如果接口的鉴权方式是Header中的Token,情况就完全不同了。Token的添加必须通过JavaScript手动完成,通常是从LocalStorage或内存中读取后写入请求头。跨域请求若要携带自定义Header,必须经过CORS(跨域资源共享)预检,并且服务器端显式允许该Header字段。恶意网站无法读取受害者在目标站点的LocalStorage数据,也无法通过CORS预检,因此CSRF攻击在此场景下自然失效。 由此可以得出一个初步结论:CSRF的攻击面与鉴权凭证的存储位置直接相关。凭证在Cookie中,风险高;凭证在Header中,CSRF基本不适用,但会引入XSS和CORS配置风险。

为什么会有Cookie、Session、Token这些方案 HTTP协议是典型的无状态协议

每次请求都是独立的,服务器无法从协议层面判断两个请求是否来自同一个用户,也无法知道用户当前处于什么操作状态。 但业务需要状态。用户登录后,购物车里的商品、个人中心的信息、操作权限的区分,都需要服务器识别当前请求属于哪个用户。于是,鉴权机制应运而生。Cookie最早解决了“浏览器端保存状态”的问题,Session解决了“服务器端保存状态”的问题,而Token(特别是JWT)则试图在分布式和无状态的服务架构下找到更灵活的方案。 理解它们出现的原因,比背诵定义更重要。因为当你面对一个真实项目时,选择哪种方案,往往取决于你的架构是单体还是微服务,是前后端同源部署还是完全分离。

Cookie与Session

存储在客户端与服务器端的本质差异 Cookie是服务器发送给浏览器的一小块数据,浏览器会将其保存在本地,并在后续请求中自动携带。它存储的是具体信息,比如用户ID、偏好设置或者一个会话标识。 Session则将数据保存在服务器端。服务器为每个登录用户创建一份独立的会话数据,并生成一个唯一的Session ID。这个ID通常通过Cookie下发给浏览器(也有URL重写的方式,但极少使用),浏览器后续请求带上这个ID,服务器据此在内存或缓存中找到对应的会话数据。 两者最核心的区别在于数据存储的位置: | 对比维度 | Cookie | Session | |———|——–|———| | 存储位置 | 浏览器本地 | 服务器端 | | 安全性 | 可被用户查看和篡改,存在XSS窃取风险 | 数据不暴露给客户端,相对安全 | | 生命周期 | 由Expires或Max-Age控制,可持久化 | 默认随浏览器会话结束而失效,服务端可设置超时时间 | | 数据大小 | 单个Cookie约4KB限制 | 理论上无大小限制,受服务器内存制约 | | 性能影响 | 无服务器存储压力,但每次请求携带数据 | 高并发下需要处理Session同步与存储问题 | | 适用场景 | 保存少量非敏感信息(如语言偏好、主题) | 保存用户登录态、购物车、操作记录等敏感数据 | 在单体应用中,Session的使用非常广泛。但它的痛点也很明显:如果应用部署在多台服务器上,负载均衡将请求分发到不同节点,用户的Session数据可能不在当前节点上,用户会被强制登出。解决方案包括Session粘滞、Session复制或引入Redis等集中式存储。这也是Token方案逐渐流行的原因之一。

JWT与Token鉴权

无状态方案带来的便利与新问题 JWT(JSON Web Token)是目前前后端分离项目中常见的Token实现。它由三部分组成:Header(声明算法和类型)、Payload(携带用户信息和声明)、Signature(签名,用于验证Token未被篡改)。 JWT的典型流程如下:

  1. 用户提交用户名和密码请求登录。
  2. 服务器验证凭证,生成JWT并返回给客户端。
  3. 客户端将JWT存储在LocalStorage或内存中(不建议放在Cookie中,理由见下文)。
  4. 客户端在每次请求的Authorization头或自定义Header中附带该JWT。
  5. 服务器验证JWT的签名和有效期,从中解析出用户身份,无需查询数据库或Session存储。 JWT的本质优势是服务端无状态。服务器不保存会话数据,只需要验证签名。这非常适合微服务架构和水平扩展的场景。用户登录了哪个服务节点并不重要,因为每个节点都可以独立完成验签。 但JWT也有自身的问题。最显著的是无法主动失效。服务端没有Session存储,无法将某个Token标记为失效。如果用户修改密码、被管理员封禁或主动退出,旧的JWT在到期前仍然有效。应对方案包括设置短有效期并配合Refresh Token刷新机制,或者维护一个黑名单列表——但这又引入了状态,削弱了无状态的优势。 另一个问题是Token的存储位置。如果前端将JWT存放在LocalStorage中,一旦页面被注入恶意脚本(XSS攻击),攻击者可以直接读取Token并冒充用户。如果将JWT存放在Cookie中,又回到了CSRF的风险之下。一个常见的折衷方案是:将JWT放在Cookie中,但设置SameSite属性为Strict或Lax来缓解CSRF,同时通过HttpOnly属性防止XSS读取Cookie——但这要求前端不能通过JavaScript读取Token,只能依赖浏览器自动携带,这在前后端完全分离且需要跨域调用API的场景下会产生新的限制。

鉴权方式对比

从攻击面与应用场景看选型 | 鉴权方式 | 核心凭证位置 | 主要攻击面 | 适合场景 | 接入成本 | 主要限制 | |———|————|———–|———|———|———| | Cookie + Session | Cookie存Session ID,数据在服务端 | CSRF(浏览器自动携带)、Session固定、Session劫持 | 单体应用、服务端渲染页面 | 低,框架内置支持 | 多节点部署需解决Session共享;移动端使用不便 | | Cookie(纯前端存储数据) | 浏览器本地 | XSS窃取、CSRF、数据篡改 | 保存非敏感偏好设置 | 极低 | 4KB大小限制、敏感信息禁止存放 | | Token(随机字符串) | 前端自行存储,Header携带 | XSS窃取、CORS配置不当 | 前后端分离、多端共用一套API | 中,需自行实现签发与验证 | 服务端仍需存储Token状态;存在有效期管理问题 | | JWT | 前端自行存储,Header携带 | XSS窃取、Token无法主动失效、算法混淆攻击 | 微服务、分布式、无状态API | 中高,需处理密钥管理与刷新机制 | 无法强制失效;Payload大小限制;引入密钥管理复杂度 |

由CSRF引发的鉴权测试思路 回到安全测试的视角

了解了这些鉴权方式的差异后,在测试权限相关漏洞时,可以按以下顺序进行排查: 第一,确认凭证位置。抓包看登录后的请求,鉴权字段是在Cookie中还是在Header中。如果在Cookie中,优先考虑CSRF;如果在Header中,优先考虑XSS能否拿到Token,以及CORS配置是否允许跨域读取响应。 第二,检查敏感操作的校验逻辑。密码修改、邮箱绑定、手机号更换、收货地址新增等操作,是否验证了旧密码或二次确认?如果只是依赖当前登录态,且登录态在Cookie中,那么CSRF的风险很高。如果登录态在Header中,则需要进一步确认是否有其他可被利用的入口。 第三,验证CORS配置。即使Token在Header中,如果服务端配置了过宽的CORS策略(比如Access-Control-Allow-Origin: *,且允许自定义Header),恶意网站依然可以发起带Token的请求——前提是攻击者能拿到Token。这又回到了XSS的利用链。CORS本身不直接导致漏洞,但它是放大其他漏洞的条件。 第四,关注Token的存储位置。登录后查看前端代码或LocalStorage,确认Token是否存在其中。如果存在,且页面存在任意XSS漏洞,则Token可被窃取。如果Token放在内存变量中,XSS窃取的难度会增加,但依然可以通过钩子函数篡改页面逻辑来实现请求伪造。

给读者的实践建议 基于上述分析,在开发或测试中,可以形成一套快速判断流程

开发侧:涉及用户敏感操作(改密、支付、修改绑定信息)的接口,无论使用哪种鉴权方式,都应增加额外的二次验证。如果使用Cookie+Session,务必设置SameSite属性,并对关键接口校验Referer或Origin。如果使用JWT,应设置短有效期(如15分钟)并配合Refresh Token,同时禁止将Token存放在LocalStorage中,优先考虑内存存储或HttpOnly Cookie加CSRF Token的双重方案。 测试侧:拿到一个接口先不急着测业务逻辑,先看鉴权字段在哪里。在Cookie中,把CSRF的测试用例排在前面;在Header中,把XSS和CORS的测试用例排在前面。这样能更快定位到真正可行的攻击面。 架构侧:在前后端分离项目中,没有完美的鉴权方案。Cookie+Session需要解决跨域…


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:安全诸子 陈看山 陈看山《第77篇 AI全栈 · 由CSRF引起的对常用鉴权方式总结》

评论:0   参与:  0