CSRF攻击(Cross-Site Request Forgery)
七崽爱吃小饼干2026/02/11阅读 1专栏 JavaScript
CSRF 是什么
CSRF = Cross-Site Request Forgery(跨站请求伪造) 一句话: 攻击者诱导用户在已登录的状态下,向目标网站发送用户“不知情”的恶意请求。
核心特点:
- 利用浏览器自动携带 Cookie 的机制
- 不需要窃取 Cookie,只需要借用户的身份发请求
- 攻击发生在第三方网站,受害者以为只是访问了一个普通页面
一、CSRF 攻击的前提条件
- 用户已登录目标网站(如银行、论坛、后台)
- 目标网站信任该用户的 Cookie/Session
- 攻击者构造一个会执行操作的请求(转账、改密码、删帖、关注)
- 用户在别的网站上触发这个请求(点击链接、打开图片、加载iframe)
二、最经典的攻击流程
假设:
- 目标网站:
bank.com(你已登录) - 攻击者网站:
evil.com
攻击步骤
- 你登录
bank.com,浏览器保存了bank.com的登录 Cookie - 攻击者在
evil.com放一段代码,自动向bank.com发请求 - 你打开
evil.com - 浏览器自动带上 bank.com 的 Cookie 发送请求
- bank.com 以为是你本人操作,执行转账/改密码
这就是 CSRF:跨站、伪造请求。
三、攻击示例(真实可复现)
1. 最简单:GET 型 CSRF
银行转账接口(不安全写法):
https://bank.com/transfer?to=黑客&money=10000
攻击者在自己网页放:
html
<img src="https://bank.com/transfer?to=黑客&money=10000">
你一打开,图片加载 = 发请求 = 转账。
2. 更常见:POST 型 CSRF
html
<form action="https://bank.com/transfer" method="POST">
<input type="hidden" name="to" value="黑客">
<input type="hidden" name="money" value="10000">
</form>
<script>document.forms[0].submit();</script>
自动提交表单,同样能成功。
四、CSRF 能干嘛?
只要是浏览器能自动发出去、且服务器信任 Cookie 的操作都能伪造:
- 转账
- 修改邮箱/密码
- 删帖、发贴
- 关注、点赞
- 退出登录(甚至能把你登出)
不能干嘛?
- 不能读响应内容(浏览器跨域限制,攻击者拿不到返回数据)
- 不能偷 Cookie(只是借用,不是窃取)
五、为什么 CSRF 能成功?
因为浏览器有一个铁律: 跨站请求时,会自动带上目标域的 Cookie。
不管请求来自哪个网站,只要目标是 bank.com,Cookie 就会被带上。
服务器看到 Cookie 有效 → 认为是本人 → 执行操作。
六、CSRF 防御方案
按推荐程度从高到低讲:
1. 最标准、最推荐:CSRF Token
原理:
- 服务器给页面下发一个随机 Token
- 前端请求时必须手动带上这个 Token
- 攻击者拿不到 Token → 请求无效
流程:
- 后端生成 CSRF Token,存入 Session
- 前端把 Token 放在:
- 表单隐藏域
- 请求头(如 X-CSRF-Token)
- 后端校验 Token 是否匹配
这是业界标准防御。
2. 现代方案:SameSite Cookie
Chrome 80+ 默认启用,非常有效。
设置 Cookie:
Set-Cookie: sessionid=xxx; SameSite=Lax;
三种模式:
- Strict:完全禁止跨站带 Cookie
- Lax:只允许安全的跨站(a链接、GET),禁止 POST/iframe
- None:不限制(必须配合 HTTPS + Secure)
Lax 是目前最平衡的默认方案。
3. 验证 Referer / Origin
请求头里的:
Referer:请求来源页面Origin:请求来源域名
后端只允许白名单内的来源。 缺点:
- 可被伪造(不绝对安全)
- 部分场景会丢失 Referer
4. 双重 Cookie 验证
- 后端写入一个 Cookie,如
csrf_cookie=随机值 - 前端请求时,把这个值再手动带到参数/请求头里
- 后端比对:Cookie 里的值 ≠ 提交的值 → 拒绝
攻击者跨站无法读取 Cookie,所以无法构造正确参数。
| 方案 | 原理 | 优点 | 缺点 | 推荐度 |
|---|---|---|---|---|
| CSRF Token | 后端下发随机Token,前端手动带上 | 最安全、标准方案 | 需要前后端配合 | ⭐⭐⭐⭐⭐ |
| SameSite Cookie | 限制跨站自动带Cookie | 配置简单、浏览器原生 | 老浏览器不支持 | ⭐⭐⭐⭐⭐ |
| 验证 Referer/Origin | 校验请求来源域名 | 简单 | 可伪造、部分场景丢失 | ⭐⭐ |
| 双重Cookie验证 | Cookie值再手动带回参数 | 简单 | 安全性一般 | ⭐⭐⭐ |
| 验证码/二次确认 | 人工确认操作 | 极安全 | 体验差 | ⭐⭐⭐ |
七、前端开发者必须记住的总结
- GET 不要做修改操作(查询才用 GET)
- 关键操作一定要用 CSRF Token
- Cookie 必须开 SameSite=Lax
- 不要完全依赖 Referer
- 登录态、敏感操作尽量加二次验证(短信、验证码)
八、总结
CSRF 就是:攻击者借你的浏览器、你的 Cookie,替你发恶意请求。 防御核心:让请求必须带一个攻击者拿不到的东西 —— CSRF Token。