什么是 CSRF(跨站请求伪造攻击)?
1. 定义
CSRF(Cross-Site Request Forgery) 是攻击者诱导用户在已登录目标网站的情况下,访问恶意页面或链接,从而以用户的身份向目标网站发起非预期的请求(如转账、修改密码等)。
- 核心问题:浏览器会默认携带用户的 Cookie(如登录凭证),攻击者利用这一点伪造用户身份操作。
2. 攻击流程
- 用户登录信任的网站(如
bank.com
),服务器返回登录凭证(Cookie)。 - 用户访问攻击者的恶意页面(如钓鱼邮件中的链接)。
- 恶意页面自动向
bank.com
发送请求(如转账操作),浏览器自动携带用户的 Cookie。 - 服务器认为这是用户的合法操作,执行请求。
示例:
html
<!-- 恶意页面中隐藏的转账请求 -->
<img src="https://bank.com/transfer?to=hacker&amount=100000" />
3. CSRF 攻击类型
类型 | 触发方式 | 示例 |
---|---|---|
GET 型 | 通过 img 、iframe 的 src 属性自动发送 GET 请求。 |
<img src="https://bank.com/delete-account?id=123" /> |
POST 型 | 构造隐藏的表单,页面加载时自动提交 POST 请求。 | 恶意页面中隐藏 <form action="https://bank.com/transfer" method="POST"> |
链接型 | 诱导用户点击伪装的链接(如短链),触发请求。 | <a href="https://bank.com/reset-password">点击抽奖</a> |
4. 防御措施
(1) 同源检测
- 检查
Referer
或Origin
头 :
验证请求是否来自合法的源(如只允许本站的域名)。- 缺点:某些浏览器可能不发送
Referer
,或存在被篡改的风险。
- 缺点:某些浏览器可能不发送
(2) CSRF Token
- 原理 :
在表单或请求参数中添加一个随机 Token(服务器生成并存储在 Session 或 Cookie 中),提交时验证 Token 是否匹配。- 关键点:Token 需足够随机(如 UUID),且仅对当前会话有效。
- 实现步骤 :
- 服务器生成 Token,返回给前端(如写入页面隐藏字段)。
- 前端提交请求时携带 Token(如参数或请求头)。
- 服务器校验 Token 的有效性。
(3) SameSite Cookie
-
设置 Cookie 的
SameSite
属性,限制第三方网站发送 Cookie:httpSet-Cookie: sessionID=abc123; SameSite=Strict
Strict
:禁止第三方网站携带 Cookie(如银行场景)。Lax
:允许安全方法(如 GET)的跨站请求携带 Cookie(默认值)。None
:允许所有跨站请求携带 Cookie(需配合Secure
属性)。
(4) 双重 Cookie 验证
- 前端在请求参数中额外携带 Cookie 中的某个字段(如
sessionID
),服务器校验参数与 Cookie 中的值是否一致。- 缺点:若网站存在 XSS 漏洞,Cookie 可能被窃取。
(5) 自定义请求头
- 前端在 AJAX 请求中添加自定义头(如
X-Requested-With: XMLHttpRequest
),服务器仅接受带此头的请求。- 仅适用于 API 请求,普通表单无法自动添加此头。
(6) 增加二次验证
- 对敏感操作(如支付、修改密码)要求用户二次确认(如输入密码、短信验证码)。
5. CSRF 与 XSS 的区别
特性 | CSRF | XSS |
---|---|---|
攻击目标 | 利用用户的登录状态发起伪造请求。 | 窃取用户数据或劫持会话。 |
依赖条件 | 用户需已登录目标网站。 | 目标网站存在未转义的恶意脚本输入。 |
防御重点 | Token、SameSite Cookie、Referer 检查。 | 输入过滤、输出转义、CSP。 |
6. 面试回答示例
"CSRF 是攻击者利用用户已登录的状态,诱导用户访问恶意页面,伪造请求以用户身份执行操作(如转账)。防御方法包括 CSRF Token、设置 SameSite Cookie、校验 Referer 头,以及敏感操作增加二次验证。"
快速记忆口诀
防 CSRF 三步曲:
- Token 随身带(请求携带随机 Token)。
- Cookie 锁来源(SameSite=Strict/Lax)。
- 关键操作要确认(密码、短信二次验证)。