03 无痕转账:跨站请求伪造CSRF


03 无痕转账:跨站请求伪造 CSRF

跨站请求伪造 CSRF 不偷数据,而是借受害者在目标网站已登录的会话,让浏览器替攻击者发出一个“看起来像用户自愿”的请求,从而以受害者身份执行转账、改密、发帖等敏感操作。根子在服务器无法区分“来自用户浏览器的请求”与“用户的真实意愿”,防御靠防跨站令牌与 SameSite Cookie。

注入和 XSS 都在“送进系统”上做文章,CSRF 换了打法:它什么都不注入,只是把你已属于某个网站的身份拿来当道具。浏览器有个默认行为——访问任何新页面时,会自动带上用户已存的该域 Cookie。CSRF 正是利用这个“自动携带”的特性,让服务器误以为请求出自身份验证过的用户。

一、问题与直觉:一个 GET 转账接口埋的雷

想象一个转账逻辑长这样(GET 是反例,只为了说明后果):

请求: GET /transfer?to=攻击者账号&amount=1000 效果: 直接执行转账, 不校验来源 ​

攻击者在论坛或邮件里放一张图片:

<img src="/transfer?to=攻击者账号&amount=1000"> ​

受害者已在银行站登录,浏览器带着会话 Cookie。当他打开这张图片所在的页面时,浏览器去加载图片,向银行站发出了带 Cookie 的转账请求;服务器看见“携带有效会话”,就执行了转账。用户全程毫不知情,钱已经没了。

二、核心原理:信任的错位

服务器用“请求带上了有效会话 Cookie”来证明“是我这个用户在操作”。但这个证明是不充分的——Cookie 是浏览器自动带的,它说明“这个浏览器访问过该站”,并不能证明“用户此刻真心想执行这笔操作”。攻击者要做的只是诱导浏览器向目标站发一个请求,剩下的由自动携带完成。

这也是为什么根因是“服务器无法分辨请求到底是不是用户本期主动发起的”,而不是“密码泄露”或“会话被偷”。统计上,CSRF 更常排在“已经很高危”但“最容易忽略配置”的漏洞里,因为它常被误以为“加了登录框就没事”。

三、实际影响面

能用 GET 完成的敏感操作越多,CSRF 越危险:改绑手机、改密、转账、发帖、下单。攻击者甚至能把多个操作串成一个自动脚本,让受害者一进页面就被连环操作。防御它的重点从来不是“换个接口方法”,而是让服务器能验证“这个请求确实是用户当前页面上自愿发起的”。

四、工程实践要点

  • 防跨站请求令牌(Anti-CSRF Token):敏感操作的表单或 AJAX 请求携带一个随请求会话绑定的随机令牌,服务器校验。攻击者深知不来自受害者站、无法预知令牌,因此构造的请求过不了验证。
  • SameSite Cookie 属性:把会话 Cookie 的 SameSite 设为 Lax 或 Strict,浏览器只在同站导航或有限跨站场景下携带,从源头减少跨站自动携带。
  • 用 POST 与正确语义:敏感操作绝不走 GET,避免 <img>、<link> 这类无脚本跨站自动请求就直接命中。
  • 校验 Origin/Referer 辅助:平台级再校验入站请求来源,虽然可被部分场景绕过,但作为纵深仍有价值。
  • 二次确认:关键操作要求重输密码或验证码,是用户体验可接受范围内的强兜底。

⚠️ 常见坑:把令牌放在 Cookie 里就以为安全。令牌必须是在表单体或自定义请求头里随请求提交、由服务器持久校验的随机值;放 Cookie 里等于让浏览器自动带它,攻击者的伪造请求也能带,等于没防。

五、一次完整的演练

背景:一个本地起的学生站,转账接口无令牌、未设 SameSite。操作:在另一个标签页构造一个会自动发 POST 的表单页(自提交),模拟攻击者页面。结果:用受害者会话访问该页,转账成功执行。解读:请求带上了受害者的会话 Cookie,服务器误判为自愿操作。变式:给表单加上随会话生成的令牌并在服务器端校验,同样的恶意页因没有合法令牌而被拒绝;再把 Cookie 设 SameSite=Lax,观察跨站 POST 请求不再携带会话从而也被挡。这套两措施叠加,CSRF 基本被堵死。

六、CSRF 与 XSS 的边界,别混着排查

很多新手把 CSRF 和 XSS 当成一回事,排查时会走弯路。区分清楚:XSS 是“还能在受害者浏览器里跑脚本”,CSRF 是“借受害者会话替你发请求”。前者攻的是客户端执行权,后者攻的是服务器对请求的意愿判定。一个没有 XSS 漏洞的站也可能中 CSRF,因为 CSRF 根本不需要脚本——一张 <img> 或一个自动提交的表单就够。反过来,也常有站同时中两个漏洞,XSS 里取令牌、CSRF 里替执行,形成组合拳。所以排查时先问“这个动作是被脚本驱动的,还是被浏览器自动携带的 Cookie 驱动”,再决定走 XSS 的编码修复,还是走 CSRF 的令牌与 SameSite 修复。

七、给“该不该信某个请求”画一条判定线

实际工程里,CSRF 的难点常是“我得在多少地方加校验”。这里给一条简化的判定线:凡是不产生状态变化的请求(读详情、查列表),通常不必为 CSRF 过度防护;凡是会产生状态变化的敏感操作(改密、转账、下单、换绑),一律先过三种防线——入口是否用 POST 且语义正确、是否带随会话生成的令牌并服务端校验、会话 Cookie 是否设了 SameSite。若用自定义接口(如 App 端、前后端无关工具在调)而不是浏览器页面承载,再把令牌校验换成自定义请求头或每次请求的动态凭证。把这条线写进接口评审清单,新接口上线时先过一遍,比事后补漏省事得多。判线本身也能反推:如果一次功能变更新增了状态变更类操作,却没同步走这三问,那基本可以确认它埋了 CSRF 的雷。

本节要点回顾

  • CSRF 借受害者已登录会话发请求,攻击者本身不碰用户密码与会话数据。
  • 根因是服务器无法区分“来自用户浏览器的请求”与“用户的真实意愿”。
  • GET 写入敏感操作是 CSRF 温床,务必改用 POST 并配令牌。
  • 防跨站令牌 + SameSite Cookie 是两条主力防线,须结合使用。
  • 令牌放 Cookie 等于没防,必须在表单体或自定义头内提交并由服务端校验。
作者与出处
原作者:灏天文库
来源:平台策划编纂
整理人: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U