最近秋招被问到了一些基础漏洞,再回头复习梳理一下。
漏洞成因
- 在登录态的前提下,浏览器访问域名时,默认会带上用户Cookie,这是最直接的原因。
- CSRF叫跨站请求伪造,是客户端发起的攻击,属于前端安全的范畴。
- CSRF只管打,不管response是否能被读取
攻击手法
- 通常使用hidden属性的自动提交的HTML表单,因为表单跨站提交不受 CORS 限制
- POST请求也可以受CSRF影响,表单 POST 是简单请求,不需要过预检
- 如果只校验了请求数据是否为json格式, 可以用content-type=text/plain来拼接json(content-type是为了构造简单请求,不会触发CORS预检)
- 存在XSS漏洞时,token防护方案基本失效
修复方案
Referer
- 修复成本最低的修复手法, 服务端校验客户端请求发起的Referer头
- Referer 经常没有(隐私模式、Referrer-Policy、HTTPS→HTTP)
- 建议优先校验 Origin,没有再用 Referer,两个都没有就拒绝
CORS&content-type格式校验
- 保证CORS策略没有问题
- 只接受content-type为application/json的请求
SameSite
这里首先要说明下SameSite控制的是跨站访问是否携带Cookie的问题,同站还是自动会带Cookie的,跨站和跨域不同,跨域是根据同源策略判断,但跨站是看eTLD+1(公共后缀列表)来判断是否跨站
- Strict:跨站发起请求时不携带任何Cookie信息
- Lax:顶级导航的 GET(点链接)带 Cookie,其他不携带
- None:跨站一定携带Cookie;必须要同时有secure字段
CSRF-token方案
服务端token方案
- 服务端生成的token不能只放在Cookie里,否则防护压根不生效
- 服务端生成token存放在Session或redis,并下发到response(隐藏表单或接口json)
- 客户端把服务端下发的token放在body或自定义头中(不要放在get的url里,会进 Referer、日志、浏览器历史并泄露)
- 发送请求,服务端将客户端发送的csrf-token与存储的csrf-token对比做校验
双token方案
这个方案最好的优点是服务端不需要持久化存储,减少了存储成本;最重要的点是跨域请求不能随便加自定义header;其实也读不到Cookie里的csrf-token信息;
比较常见的方案是服务端生成直接下发(比如set-cookie,但不要设置httponly),前端/客户端发起请求的时候同时在Cookie中和header中携带;当然其实也可以客户端生成,一份放Cookie一份放header
服务端校验客户端发过来的两份token是否一致
特殊绕过场景:控制不可信子域,用 Domain=父域 种一颗已知的 csrf Cookie,请求里再带同一份,双提交只校验相等时会被绕过。这个防护的话就是还是需要服务端存储token,不要完全依赖客户端的token,另外就是增加Origin和Referer校验
引入验证码&生物特征
- 敏感场景引入多因子验证,但用户体验不好,只适用于极敏感场景
本文作者:
yd0ng
本文链接: https://blog.yd0ng.top/2026/08/25/%E5%BA%94%E7%94%A8%E5%AE%89%E5%85%A8/%E5%89%8D%E7%AB%AF%E5%AE%89%E5%85%A8-CSRF/
版权声明: 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。转载请注明出处!
本文链接: https://blog.yd0ng.top/2026/08/25/%E5%BA%94%E7%94%A8%E5%AE%89%E5%85%A8/%E5%89%8D%E7%AB%AF%E5%AE%89%E5%85%A8-CSRF/
版权声明: 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。转载请注明出处!