CSRF 为什么现在少见了:SameSite 与 Token 的分工
CSRF 的前提是「已登录用户的浏览器会自动带上凭证」。攻击者不需要读响应,只要让请求发出去就够。
现代浏览器默认 SameSite=Lax 之后,跨站 POST 不再自动带 Cookie,这类漏洞因此大幅减少——但没消失。
先说结论
SameSite=Lax 打底,Token 兜住跨站与子域,危险操作再确认一次。
- 会话 Cookie 设 SameSite=Lax 或 Strict
- 写操作校验 CSRF Token(与 Session 绑定)
- 校验 Origin/Referer 作为补充
- 改密码、转账类操作要求重新验证
漏洞是怎么产生的
SameSite=Lax 允许顶级导航的 GET 带 Cookie,所以「GET 请求改状态」依然危险。
Token 的价值在于攻击者跨站拿不到它;但要注意子域可以写 Cookie,同站不同域仍需防护。
修复与验证
修复不是改一行代码,而是四件事一起做:
- 清理所有用 GET 改状态的接口
- 会话 Cookie 设置 SameSite=Lax、Secure、HttpOnly
- 表单与 AJAX 统一带 CSRF Token,服务端强校验
- 校验 Origin 头,拒绝跨站来源
- 敏感操作增加二次验证(密码/验证码)
攻击面与检测点
按影响面排序,先修影响最大的:
| 防御 | 挡住什么 | 挡不住什么 |
|---|---|---|
| SameSite=Lax | 跨站 POST | 同站子域、GET 改状态 |
| CSRF Token | 跨站伪造请求 | XSS 可读 Token |
| Origin 校验 | 跨站来源 | 非浏览器客户端 |
| 二次验证 | 高价值操作 | 用户体验成本 |

几个容易踩的坑
下面这些是最常见的错误做法:
- 只靠 Referer:可被裁剪或缺失
- Token 存在 Cookie 且不校验:等于没有
- GET 接口改状态:链接预取都能触发
- 认为 JSON 接口天然安全:表单也能构造
写在最后
CSRF 的核心是「凭证自动携带」。让凭证不自动跨站,问题就解决一大半。
安全不是一次加固,是持续的假设:假设输入不可信、假设边界会破、假设有人会看错。
评论 (3)
修复清单比漏洞描述有用多了,很多文章只讲怎么打不讲怎么防。
白名单那条永远是最有效的,正则黑名单迟早绕过。
建议再补一条:把这类检查加到 CI 里,靠人记必然漏。
发表评论