
文章目录一、用一句话讲透原理二、攻击长什么样认识即可1. 经典自动提交的表单2. 图片 / 链接触发的 GET3. JSON 接口就一定安全吗4. 登录 CSRF 与其它变体三、防御总纲你要证明“这是用户本人意图”四、CSRF Token仍然是基本功1. 同步器令牌模式2. 双提交 CookieDouble Submit3. 框架优先五、Origin / Referer 校验六、SameSite Cookie现代浏览器的“半自动防线”1. SameSite 是干什么的2. Lax 为什么常常“够用却不够”3. Strict 的代价4. None 用在什么地方5. 和“站”的定义有关6. SameSite 解决不了什么七、推荐的组合策略2020 年代务实版对外 Web 应用纯 API Bearer Token前端存内存Cookie 会话的 SPA第三方支付回调 / Webhook八、授权测试怎么测 CSRF九、常见翻车现场十、收尾附SameSite 选择速查做安全的人里有一批人对 CSRF 的第一印象是“不就是表单里加个 token 吗”做业务的人里另一批人的第一印象是“我们全是 JSON 接口好像不太怕。”两边都只对了一半。CSRFCross-Site Request Forgery跨站请求伪造的核心从来不复杂——浏览器会在跨站请求里自动带上目标站的 Cookie在策略允许时——可一旦碰上 SameSite 默认值变化、前后端分离、移动 WebView、文件上传、GET 误伤业务坑就会一个个冒出来。一、用一句话讲透原理你已经登录了银行站点bank.example浏览器里躺着会话 Cookie。你另开一个标签访问了恶意页evil.example。恶意页可以让你的浏览器向bank.example发起一个请求——比如“转账”。关键在于在很多历史默认行为下浏览器发这个请求时会自动附带bank.example的 Cookie。服务器若只靠“有没有合法会话 Cookie”判断“是不是用户本人意愿”就会把跨站伪造的请求当成用户点的。所以 CSRF 骗的不是密码是服务器对浏览器自动凭证的信任。和 XSS 对比一下更好记XSSCSRF核心在目标站上下文执行攻击者脚本借用用户浏览器向目标站发请求要不要目标站有漏洞页通常要有注入点要有“只认 Cookie、不认意愿”的接口典型结果偷会话、改页面、继续作恶以用户身份完成状态变更XSS 有时能直接做完 CSRF 能做的事但没有 XSS 时CSRF 仍可能单独成立。两者都要防。二、攻击长什么样认识即可1. 经典自动提交的表单恶意页里放一个自动提交到目标站的表单POST用户一旦打开恶意页浏览器就带着 Cookie 把请求打出去。用户可能只看到页面闪一下账户状态却变了。2. 图片 / 链接触发的 GET若危险操作竟然用 GET 就能完成例如GET /delete?id1那一张img src...都可能触发。这首先是业务接口设计错误改变状态的操作不该是 GET。即便防了 CSRF也应改成 POST/PUT/DELETE 鉴权。3. JSON 接口就一定安全吗不完全。确实简单 HTML 表单很难发Content-Type: application/json的复杂请求浏览器的 CORS 预检也会挡一批“跨域读响应”。但 CSRF 关心的往往是请求有没有副作用不是攻击者能不能读返回值。仍需小心服务端若接受text/plain等方式“擦边”解析出 JSON某些接口其实也吃表单编码同站点子域被拿下后的“跨站”边界更细配合 XSS / 子域接管时SameSite 与 CORS 模型会更复杂。结论前后端分离 ≠ 自动免疫 CSRF要看 Cookie 怎么带、接口怎么鉴权。4. 登录 CSRF 与其它变体还有“强迫用户登录成攻击者账号”一类登录 CSRF用于后续投毒或追踪。是否划进你们的威胁模型取决于业务。支付、改密、授权绑定、关闭 MFA 等一律按高危状态变更保护。三、防御总纲你要证明“这是用户本人意图”会话 Cookie 证明“浏览器里有谁的登录态”CSRF 防御要额外证明“这次请求是用户在本站上下文里发起的”。常见积木CSRF Token同步器令牌 / 双提交 Cookie 等检查 Origin / RefererSameSite Cookie不用 Cookie 做会话如 Authorization Bearer注意仍有别的风险关键操作二次确认 / 重新输入密码 / MFAGet 无副作用实战里很少只靠一样。SameSite 大幅降低了成本但不是万能符。四、CSRF Token仍然是基本功1. 同步器令牌模式服务端给每个会话或每次表单下发随机 token存在服务端会话里。浏览器提交状态变更时必须带上这个 token表单隐藏域或自定义头。服务端校验 token 与会话绑定一致。攻击者的站点读不到你的页面内容受同源策略限制也就拿不到 token——于是跨站请求缺令牌被拒。要点token 要不可预测、足够长验证失败要拒绝不要“没带也行”注意刷新、多标签页、缓存页面导致的 token 过期体验问题SPA 常见做法从 cookie 读 token 再复制到 Header见双提交或由后端接口下发到前端内存。2. 双提交 CookieDouble Submit服务端设一个 CSRF Cookie前端 JS 读取后放到请求头如X-CSRF-Token。服务端比较 Cookie 与 Header 是否一致。它依赖攻击者不能轻易读写你的 Cookie也不能在跨站场景下方便地设置你的域 Cookie 并同时控制头结合现代浏览器策略。实现细节一错例如 Cookie 过于宽松、子域可写就会翻车。框架自带实现通常比手搓安全。3. 框架优先Django、Rails、Spring Security、ASP.NET、Laravel 等几乎都有现成 CSRF 中间件。优先用框架别在业务里东一块西一块。五、Origin / Referer 校验服务端检查Origin或Referer是否为本站可信来源。跨站表单请求往往会带上恶意源或在某些情况下缺失。优点实现相对简单对传统表单 CSRF 有效。缺点与坑Referer 可能被隐私策略、浏览器设置裁掉误杀合法无 Referer 的客户端只靠 Referer 不如 Origin 清晰需维护可信域列表含多域名站点。实操建议能拿 Origin 先拿 Origin缺失时策略要明确拒绝或走额外校验与 token 组合更稳。六、SameSite Cookie现代浏览器的“半自动防线”1. SameSite 是干什么的Cookie 的SameSite属性控制在跨站请求中是否携带该 Cookie。常见值值含义直观理解Strict跨站请求基本不带这个 Cookie最严Lax跨站“导航式”GET 等部分场景可能带常见跨站 POST 不带None跨站也可带但通常要求同时Secure仅 HTTPS浏览器近几年把默认策略收紧许多场景默认按 Lax 思路处理未声明的 Cookie具体以浏览器为准。这让大量“裸 POST 会话 Cookie”的老式 CSRF自然失效了一大截——好事但别据此拆掉服务端校验。2. Lax 为什么常常“够用却不够”Lax下用户从外站点开一个链接顶级导航 GET进入你的站时仍可能带上 Cookie——这是为了体验外链进站保持登录。因此若你的危险操作可用 GET 完成Lax 挡不住。再次强调状态变更用 POST 等并配合 token。3. Strict 的代价更安全但用户从外部链接点进网站可能呈现未登录体验受损。高安全后台、管理端可以上 Strict对 C 端大站更多用 Lax CSRF token。4. None 用在什么地方跨站需要带 Cookie 的场景第三方嵌入、某些 SSO、跨站 API本身就很敏感。必须Secure必须 HTTPS必须清楚自己在扩大 CSRF 攻击面——此时更要有 token 或其它强校验不能只靠 SameSite。5. 和“站”的定义有关SameSite 里的“站site”按 eTLD1 等规则理解和“源origin”不完全一样。a.example.com与b.example.com在 SameSite 看来可能是同站但在同源策略上不同源。子域接管、兄弟子域 XSS会让“同站 Cookie”模型更危险。子域安全与 Cookie 域范围Domain要一起设计。6. SameSite 解决不了什么同站内的请求伪造子域恶意页面打主域接口非 Cookie 凭证方案下的其它伪造用户已被 XSS 的情况SameSiteNone的跨站带 Cookie 场景GET 副作用接口在 Lax 下的风险。所以官方与业界共识接近SameSite 是显著缓解不是完整替代 CSRF token。七、推荐的组合策略2020 年代务实版对外 Web 应用会话 CookieSecureHttpOnlySameSiteLax或管理端 Strict所有状态变更CSRF token 或框架等价物校验 Origin可作附加层GET/HEAD 无副作用改密、转账、授权二次验证。纯 API Bearer Token前端存内存不自动带 Cookie天然规避经典 CSRF。但要注意 XSS 偷 token、token 存储位置、刷新令牌泄漏。不是“更安全的免费午餐”是换威胁模型。Cookie 会话的 SPA依然按 Cookie 场景防 CSRF双提交或同步器令牌别假设 JSON 万能。第三方支付回调 / Webhook那是服务端到服务端应用签名校验不走浏览器 CSRF 模型。别和浏览器 CSRF 混为一谈。八、授权测试怎么测 CSRF登录受害者账号抓一条状态变更请求去掉 token / 改坏 token看是否仍成功——应失败用跨站 HTML 复现靶场观察 Cookie 是否带上、结果是否变更检查 Cookie 的 SameSite / Secure / HttpOnly扫一遍危险 GET子域、多域名、跨站 iframe 场景单独评估。报告里写清接口、方法、缺了哪层防护、SameSite 现状、修复建议。不要在真实用户账户上做破坏性演示。九、常见翻车现场“我们加了 token但有的接口忘了。”全局中间件白名单要极短且审计。“Token 放在 Cookie 里又没校验头等于没防。”“全站 SameSiteNone 为了嵌入。”等于主动回到跨站带 Cookie 时代必须强 token。“Referer 全拦APP 内 WebView 误伤。”要区分客户端用组合策略。“有 XSS 还纠结 CSRF。”先修 XSSXSS 在时可直接操作用户会话。“跨域 CORS 配了 Access-Control-Allow-Origin: * 还带凭证。”这是灾难级配置。带 Cookie 的 CORS 必须精确源绝不能*。十、收尾CSRF 的原理薄如纸浏览器自动递凭证服务器误当成用户点头。防住它的思路也稳定再要一个“只有本站页面才拿得到的证据”——token、严格的源校验再加上 SameSite 这道浏览器给的缓冲。SameSite 让今天的默认世界比十年前安全但它不会替你改掉危险的 GET不会替你看好SameSiteNone也不会替你防守子域和 XSS。把它当保险杠把 token 与正确的会话设计当刹车。今晚若只做一件事打开浏览器开发者工具看你们主站会话 Cookie 有没有SameSite和Secure再随便抓一个改资料/下单请求看有没有 CSRF token 或等价头。两眼看完你就知道自己站在“靠浏览器默默挡着”还是“纵深真的做了”。附SameSite 选择速查场景更常见选择普通 C 端站点会话Lax CSRF token高安全后台Strict token必须跨站带 CookieNone; Secure 强 token 极小范围无 Cookie 会话 APIBearer 等 防 XSS