前言
如果说 XSS 是“脚本注入”,那么 CSRF (Cross Site Request Forgery) 就是“借刀杀人”。攻击者并不直接窃取你的数据,而是盗用你的登录身份,骗取服务器的信任,替你执行恶意操作(如转账、修改密码)。
一、 CSRF 攻击的本质
CSRF 攻击成功的核心在于:浏览器在发送 HTTP 请求时,会自动携带该域名下的 Cookie。 只要你没退出登录,黑客就能利用你的身份在后台“为所欲为”。
二、 场景重现:一次无声的“盗号”
- 登录受信任网站 A:用户登录银行站点
bank.com,浏览器获取了身份 Cookie。 - 访问恶意网站 B:用户在未退出银行站点的状态下,被诱导打开了攻击者的页面。
- 恶意代码触发:网站 B 的代码中隐藏了一个指向
bank.com/transfer?amount=10000&to=hacker的请求(可能是通过<img>标签或自动提交的表单)。 - 浏览器“助纣为虐” :由于是发往
bank.com的请求,浏览器会自动带上用户的 Cookie。 - 服务器被骗:银行服务器检查 Cookie 发现是合法用户,于是完成了转账。
三、 全方位防御策略
1. 验证来源:Referer 与 Origin 字段
服务器通过检查 HTTP 头部信息,判断请求是否来自合法的域名。
-
Referer:包含完整的来源 URL 路径。
-
Origin:仅包含域名信息(不带路径),更隐私安全。
-
策略:优先验证
Origin,缺失时再校验Referer。如果来源地址不在白名单内,则拒绝服务。注:Referer 在某些隐私模式或旧版浏览器中可能被修改或隐藏,因此不能作为唯一防线。
2. 引入“防伪令牌”:CSRF Token
既然黑客能利用 Cookie,那我们就用黑客拿不到的东西。
- 原理:在用户请求页面时,服务器生成一个随机、不可伪造的 Token 返回给前端。
- 执行:前端后续发送请求时(如 POST),必须在请求头或表单中手动带上这个 Token。
- 效果:黑客只能触发请求携带 Cookie,但无法获取并伪造你的 Token。
3. 设置 Cookie 的 SameSite 属性(现代方案)
这是目前最优雅的解决方案,通过浏览器底层限制 Cookie 的跨站传递。
| 取值 | 限制程度 | 行为描述 |
|---|---|---|
| Strict | 最高 | 完全禁止第三方携带 Cookie。只有从本站发起的请求才会带上。 |
| Lax | 默认 | 导航到第三方站点的 GET 请求(链接跳转)可带,但 POST、img、iframe 均不带。 |
| None | 最低 | 任何情况都发送,但必须配合 Secure 属性(仅 HTTPS)使用。 |
四、 扩充防御策略
- 双重确认机制:针对敏感操作(转账、注销),除了以上防范,还应加入验证码、支付密码等需要用户手动交互的环节,这是防御 CSRF 的最终底线。
- GET 请求规范化:严格遵守 RESTful 规范,GET 请求仅用于数据查询,绝不用于修改数据。这样可以天然规避大部分通过
<img>或<a>标签发起的 CSRF。