什么是 CSRF?
CSRF(Cross-Site Request Forgery,跨站请求伪造)是一种利用 浏览器自动携带 Cookie 的机制,诱骗用户在已登录目标网站的情况下,执行恶意操作的攻击方式。
攻击核心特点:
- 攻击者 不需要窃取 Cookie,而是利用浏览器自动发送 Cookie 的机制。
- 服务器无法区分 用户主动提交的请求和 恶意网站伪造的请求。
CSRF 攻击流程
示例场景(银行转账)
-
用户登录银行网站
访问your-bank.com,服务器设置Cookie并返回:
httpSet-Cookie: session_id=abc123; Secure; HttpOnly
浏览器存储该 Cookie,后续访问
your-bank.com
时自动携带。 -
用户访问恶意网站
恶意网站malicious.com隐藏了一个自动提交的表单:
html<form action="https://your-bank.com/transfer" method="POST"> <input type="hidden" name="amount" value="10000"> <input type="hidden" name="to_account" value="hacker"> </form> <script> document.forms[0].submit(); // 自动提交 </script>
-
浏览器发送伪造请求
由于目标地址是your-bank.com,浏览器自动附加 Cookie
httpPOST /transfer HTTP/1.1 Host: your-bank.com Cookie: session_id=abc123 amount=10000&to_account=hacker
服务器看到合法
session_id
,执行转账,攻击成功!
CSRF 防御措施
(1)CSRF Token(最常用)
原理:服务器生成随机 Token,嵌入表单,提交时验证。
实现步骤:
-
服务器在渲染表单时生成 Token,存储(Session/Redis):
html<form action="/transfer" method="POST"> <input type="hidden" name="csrf_token" value="RANDOM_STRING"> </form>
-
提交请求时,服务器验证 Token 是否匹配:
pythonif request.cookies["session_id"] != user_session or request.form["csrf_token"] != stored_token: return "Invalid request!"
-
恶意网站无法获取 Token,伪造请求会被拒绝。
(2)SameSite Cookie(浏览器级防御)
通过设置 SameSite
属性,限制跨站请求携带 Cookie。
SameSite属性有三个值:
- Strict模式(最严格、但可能影响用户体验)
仅在请求来源与当前域名完全一致时发送Cookie,所有跨站请求均不携带。安全性最高,但可能影响用户体验(如从外部链接跳转时需重新登录)。
-
Lax模式(推荐、默认值)
允许在GET请求的顶级导航(如点击链接跳转)中发送Cookie,但禁止跨站的POST请求或其他非安全方法携带Cookie。平衡安全性与用户体验,成为主流浏览器的默认配置。httpSet-Cookie: session_id=abc123; Secure; HttpOnly; SameSite=Lax
- None模式
允许所有跨站点请求携带Cookie,但必须同时设置Secure
属性(仅通过HTTPS传输)。
(3)检查 Referer/Origin 头
服务器检查 Referer
(表示当前请求是从哪个 URL 页面发起的) 或 Origin
(当前请求的 发起源,仅含协议 + 域名 + 端口,不含路径),判断请求来源是否合法。
缺点:Referer
可能被篡改或缺失,不适合作为唯一防护。