宁夏回族自治区网站建设_网站建设公司_前后端分离_seo优化
2026/1/7 15:36:36 网站建设 项目流程

一文吃透 CSRF 攻击:原理、经典漏洞与落地级防御方案

在 Web 安全领域,CSRF(Cross-Site Request Forgery,跨站请求伪造)是仅次于 XSS 的经典漏洞,常被攻击者用来窃取用户权限、执行恶意操作(如转账、修改密码、删除数据)。据 OWASP 统计,2025 年全球企业 Web 应用中,仍有 32% 存在 CSRF 风险,其中金融、政务类系统因涉及敏感操作,受攻击后损失更为严重。

本文将从核心原理、经典漏洞案例、全方位防御方案三个维度,用通俗语言 + 实战代码拆解 CSRF,帮助开发者快速识别风险、落地防御措施。

一、CSRF 核心原理:“借刀杀人” 的攻击逻辑

  1. 漏洞本质
    CSRF 的核心是利用用户的合法身份(已登录状态),诱导用户触发恶意构造的请求,让服务器误以为是用户的主动操作。
    简单类比:你刚登录银行 App(已获得合法身份凭证 Cookie),随后不小心点开一条恶意链接,链接背后的攻击者提前构造了 “向攻击者转账 1 万元” 的银行转账请求,银行服务器看到你已登录(Cookie 有效),就执行了这笔恶意转账。
  2. 攻击成立的 3 个核心条件
  1. 完整攻击流程
  2. 与 XSS 的核心区别
    很多开发者会混淆 CSRF 和 XSS,关键差异在于:
    XSS:利用网站的输入输出漏洞,向网站注入恶意脚本,获取用户的敏感信息(如 Cookie);
    CSRF:不获取 Cookie,而是直接利用用户已有的 Cookie 身份,伪造合法请求;
    关系:XSS 可以辅助 CSRF 攻击(如通过 XSS 获取用户 Cookie 后,精准构造请求),但两者是独立漏洞。

二、经典 CSRF 漏洞案例:从 GET 到 POST 的攻击场景

1. 案例 1:GET 请求型 CSRF(最易利用)

漏洞场景

某后台管理系统的 “删除用户” 接口采用 GET 请求,参数为用户 ID:
http://xxx.com/admin/deleteUser?id=123
只要用户触发这个 URL,且处于登录状态,服务器就会执行删除操作。

攻击构造

攻击者在恶意网站中嵌入一张隐藏图片,图片地址就是伪造的删除请求:

<!-- 恶意网站中的隐藏代码 --> <img src="http://xxx.com/admin/deleteUser?id=123" style="display:none">

当用户访问恶意网站时,浏览器会自动请求这张 “图片”(实际是删除请求),由于用户已登录,服务器直接执行删除操作。

漏洞核心问题

用 GET 请求处理敏感操作(删除、修改、转账);
服务器未对请求的合法性进行额外验证。

2. 案例 2:POST 请求型 CSRF(稍复杂但危害更大)

漏洞场景

某银行转账接口采用 POST 请求,核心参数为toUser(收款方)、money(金额):

<!-- 银行正常转账表单 --> <form action="http://bank.com/transfer" method="POST"> <input name="toUser" value="456"> <!-- 收款方ID --> <input name="money" value="10000"> <!-- 金额 --> <button type="submit">转账</button> </form>

攻击构造

攻击者在恶意网站中构造自动提交的 POST 表单(无需用户点击,加载页面即提交):

<!-- 恶意网站中的自动提交表单 --> <form id="csrfForm" action="http://bank.com/transfer" method="POST"> <input name="toUser" value="攻击者ID"> <input name="money" value="10000"> </form> <script> // 页面加载后自动提交表单 document.getElementById("csrfForm").submit(); </script>

用户访问恶意网站后,表单自动提交,银行服务器验证用户已登录,执行转账操作。
漏洞核心问题

虽然用了 POST 请求,但仅依赖 Cookie 验证身份,未对请求来源、合法性进行验证。

三、全方位防御方案:从简单到复杂,层层递进

CSRF 防御的核心思路是:让服务器能区分 “用户主动发起的请求” 和 “攻击者伪造的请求”。以下是 5 种落地级防御方案,按优先级和实现难度排序:

1. 方案 1:使用 Token 验证(最常用、最有效)

核心原理

在用户登录后,服务器生成一个随机且唯一的 CSRF-Token,嵌入到页面表单或响应头中;用户提交请求时,必须携带这个 Token,服务器验证 Token 的有效性(是否存在、是否正确、是否过期),验证通过才执行操作。

实战实现(以 Python Flask 为例)

后端生成并存储 Token(关联用户 Session):


2.前端表单携带 Token:

<!-- 前端表单嵌入Token --> <form action="/transfer" method="POST"> <input name="toUser" value="456"> <input name="money" value="10000"> <!-- 隐藏的CSRF-Token字段 --> <input type="hidden" name="csrf_token" value="{{ csrf_token }}"> <button type="submit">转账</button> </form>

关键注意事项

Token 必须随机、唯一,且过期时间短(如 30 分钟);
Token 不能通过 URL 传递(避免被日志记录、缓存泄露);
后端需严格验证 Token,不能仅前端验证(前端验证可被绕过)。

2. 方案 2:设置 SameSite Cookie(现代浏览器首选)

核心原理

通过设置 Cookie 的SameSite属性,限制 Cookie 仅在 “同站点请求” 中携带,禁止跨站请求携带 Cookie,从根源上阻断 CSRF 攻击。

SameSite 的 3 个属性值


实战配置

1.后代码设置(Flask 示例):

# 登录时设置Cookie,指定SameSite=Strict @app.route("/login", methods=["POST"]) def login(): response = make_response("登录成功") # 设置Cookie:user_id=123,SameSite=Strict,Secure(HTTPS环境),HttpOnly(防止XSS窃取) response.set_cookie("user_id", "123", samesite="Strict", secure=True, httponly=True) return response

2.服务器配置(Nginx 示例):

# Nginx配置Cookie的SameSite属性 add_header Set-Cookie "user_id=$cookie_user_id; SameSite=Strict; Secure; HttpOnly";

优缺点
优点:无需修改业务代码,配置简单,兼容性好(Chrome 51+、Firefox 60+、Edge 79 + 均支持);
缺点:依赖浏览器支持(老旧浏览器无效),无法解决 “同站点内的 CSRF 攻击”(如同一网站内的恶意页面)。

3. 方案 3:验证 Referer/Origin 请求头

核心原理

HTTP 请求中,Referer头会携带请求的来源页面 URL,Origin头会携带请求的来源站点(无路径信息)。服务器通过验证这两个头,只允许来自可信域名(如自身域名)的请求,拒绝跨站请求。

实战实现(Flask 示例)

@app.route("/transfer", methods=["POST"]) def transfer(): # 验证Referer(仅允许来自本域名的请求) referer = request.headers.get("Referer") if not referer or not referer.startswith("http://your-domain.com"): return "CSRF攻击拦截(Referer验证失败)", 403 # 或验证Origin(更安全,仅校验站点) origin = request.headers.get("Origin") if origin and origin != "http://your-domain.com": return "CSRF攻击拦截(Origin验证失败)", 403 # 执行转账逻辑... return "转账成功", 200

优缺点
优点:实现简单,无需前端配合;
缺点:
Referer 可被篡改或隐藏(如部分浏览器支持通过 meta 标签禁用 Referer);
Origin 在部分请求中不存在(如直接输入 URL 的 GET 请求);
无法应对 “同域名下的恶意请求”。

4. 方案 4:规范请求方法,避免敏感操作使用 GET

核心原理

GET 请求的参数会暴露在 URL 中,易被攻击者构造恶意链接;而 POST 请求的参数在请求体中,构造攻击的成本更高。因此,所有敏感操作(转账、修改密码、删除数据)必须使用 POST/PUT/DELETE 等非 GET 方法。

注意事项

仅用 POST 方法不能完全防御 CSRF(如案例 2 中的 POST 型 CSRF),需配合 Token 或 SameSite Cookie;
前端需隐藏敏感操作的接口地址,避免攻击者轻易获取接口参数格式。

5. 方案 5:双重验证(高敏感场景补充)

核心原理

对于核心敏感操作(如大额转账、修改绑定手机号),除了常规的身份验证和 CSRF 防御,额外增加一层验证(如短信验证码、邮箱验证码、U 盾验证),即使 CSRF 攻击触发,也因缺少第二层验证而失败。

适用场景

金融系统的大额交易、政务系统的核心权限操作、用户中心的敏感信息修改。

四、实战避坑指南:这些错误别再犯!

  1. 仅依赖前端验证 CSRF-Token:前端验证可被攻击者通过修改 JS 代码绕过,核心验证必须在后端;
  2. Token 重复使用或长期有效:Token 需随机生成、关联用户 Session,且过期时间不宜过长(建议 30 分钟内);
  3. 忽略 HTTPS 的重要性:未启用 HTTPS 时,Cookie 和 Token 可能被中间人窃取,导致防御失效;
  4. 认为 “有 XSS 防御就不用防 CSRF”:XSS 和 CSRF 是不同类型漏洞,需分别防御;
  5. 对所有接口都用严格的防御:非敏感接口(如查看新闻、获取商品列表)可适当简化防御(如仅用 SameSite Cookie),平衡安全性和性能。

五、总结

CSRF 攻击的核心是 “借用户身份行恶意操作”,防御的关键是 “让服务器能区分请求的合法性”。对于大多数 Web 应用,推荐采用 “Token 验证 + SameSite Cookie” 的组合防御方案:

作为开发者,在日常开发中需养成 “敏感操作必防 CSRF” 的习惯,同时定期通过渗透测试(如使用 Burp Suite 构造 CSRF 请求)验证防御效果。如果需要更多语言(如 Java、PHP)的 CSRF 防御代码示例,或想了解 CSRF 与其他漏洞的组合攻击防御,可在评论区留言交流。

网络安全学习资源

网上虽然也有很多的学习资源,但基本上都残缺不全的,这是我们和网安大厂360共同研发的的网安视频教程,内容涵盖了入门必备的操作系统、计算机网络和编程语言等初级知识,而且包含了中级的各种渗透技术,并且还有后期的CTF对抗、区块链安全等高阶技术。总共200多节视频,100多本网安电子书,最新学习路线图和工具安装包都有,不用担心学不全。

🐵这些东西我都可以免费分享给大家,需要的可以点这里自取👉:网安入门到进阶资源

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询