CSRF 防护必须依赖前后端协同的防伪令牌(AntiForgeryToken),仅靠 SameSite=Lax 或 Cookie 校验无效;需满足一次性、绑定会话、传输隔离三条件,并严格实施前端渲染+后端校验+AJAX 手动传递。

HTML 表单本身不防跨站提交,所谓“防止被黑”,本质是防止 CSRF(跨站请求伪造)——浏览器会自动带上 Cookie 提交表单,攻击者只需诱导用户访问恶意页面,就能静默发请求。不加防护的表单等于把转账按钮裸挂在公网。
为什么 是 CSRF 最高危入口
因为它是唯一能绕过同源策略、自动携带 Cookie、无需预检、JS 可静默触发的跨域 POST 通道: 只能 GET,fetch 和 XMLHttpRequest 被 CORS 拦着,唯独 提交天然“合法”且隐蔽。
常见错误现象包括:用户没点提交按钮,但密码被改了、订单被下了、权限被删了;日志里看到来源域名是 attacker.com,但 Cookie 和 Session 都有效。
- 攻击者在自己页面写一个隐藏
,用 JS 自动 submit - 用户已登录 yoursite.com,浏览器照常附上 Cookie
- 服务端只校验 Cookie 和参数格式,就执行了敏感操作
@Html.AntiForgeryToken() 在 ASP.NET MVC 中怎么不漏配
这个辅助方法只是生成 token 字段,真正起作用的是前后端协同校验。漏一环就等于没加。
必须同时满足以下四点:
- 前端每个需要防护的表单内调用
@Html.AntiForgeryToken(),它会输出 - 后端对应 Action 方法加
[ValidateAntiForgeryToken]特性,否则 token 完全不校验 - AJAX 请求不能依赖表单自动带 token,得手动取值:
$('input[name=__RequestVerificationToken]').val(),再塞进headers: { 'RequestVerificationToken': token } - 若用 Web API 或前后端分离架构,
[ValidateAntiForgeryToken]默认不生效(它只认 form post + cookie),得换[AutoValidateAntiforgeryToken]或自定义过滤器
SameSite=Lax 能不能代替 CSRF Token
不能。它只是缓解手段,不是替代方案。
SameSite=Lax 在 Chrome 80+ 后对大部分跨站表单 POST 有拦截效果,但它在这些场景下可能失效:
- Safari 旧版本(尤其是 iOS 12 之前)完全不支持
- 安卓 WebView 内嵌页行为不一致
- iframe 嵌套中某些提交方式(如
target="_top")可能绕过 - 攻击者可诱导用户先访问目标站再跳转,构造“同站”上下文
所以生产环境必须用 token,SameSite 只能作为第二道防线,和 HTTPS、CSP 等一起部署。
CSRF Token 必须满足的三个硬条件
随便生成个随机字符串塞进表单,不等于安全。token 本身要经得起推敲:
- 一次性:每次新表单渲染都生成新值,提交后立即失效(或至少 session 内不可重放)
- 绑定会话:token 值和服务端 session 存储的值必须严格比对(用
===,不是==),且不能从 URL 或 Referer 中读取 - 传输隔离:token 不该放在 Cookie(除非 HttpOnly 关闭且 JS 明确读取),更不该拼在 URL 里;应走表单隐藏字段或请求头
最容易被忽略的是“一次性”——很多项目只做生成和比对,却没清空或轮换 session 中的 token,导致重放攻击可行。别省那一行 Session.Remove("CSRF_TOKEN")。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











