什么是CSRF攻击?如何防范?
2026/03/12 14:59
瀏覽16
迴響0
推薦0
引用0
什么是 CSRF 攻击?如何防范?
作者:在线ddos压力测试【网址:kv69.com】
在《什么是 XSS 攻击?如何防范?》这篇文章中,我们深入探讨了跨站脚本攻击(Cross-Site Scripting,简称 XSS)的原理、危害以及相应的防御策略。作为网络安全领域的重要组成部分,理解并防范各类攻击手段对于开发者和普通用户都至关重要。在本文中,我们将继续聚焦另一种同样常见且危害巨大的网络攻击方式——跨站请求伪造(Cross-Site Request Forgery,简称 CSRF)。本文将用简体中文全面解析 CSRF 攻击的本质、运作机制、真实案例、防御方案以及最佳实践,帮助读者建立系统化的安全防护认知。
一、深入理解 CSRF 攻击的本质
1.1 什么是 CSRF 攻击?
CSRF,全称为 Cross-Site Request Forgery,中文译为"跨站请求伪造"。这是一种利用用户已登录身份,在其不知情的情况下,诱导浏览器向目标网站发送恶意请求的攻击方式。攻击者通过精心构造的链接、图片或脚本,诱使用户在已认证的网站上执行非本意的操作,如修改密码、转账汇款、更改邮箱、发布内容等敏感行为。
与 XSS 攻击不同,CSRF 并不直接在目标网站注入恶意代码,而是"借用"用户的合法身份和权限,让服务器误认为这些恶意请求是用户本人自愿发起的。因此,CSRF 攻击的核心在于"身份冒用"而非"代码注入"。
1.2 为什么 CSRF 攻击能够成功?
要理解 CSRF 为何能够得逞,我们需要先了解现代 Web 应用的身份认证机制。大多数网站采用基于 Cookie 的会话管理方式:当用户成功登录后,服务器会生成一个唯一的会话标识(Session ID),并通过 Set-Cookie 响应头将其发送给浏览器。此后,浏览器在向该域名发起请求时,会自动携带这个 Cookie,服务器据此识别用户身份。
这种机制的便利性在于用户无需每次操作都重新输入账号密码,但同时也埋下了安全隐患:只要用户未主动登出,且 Cookie 未过期,浏览器就会在访问该域名下的任何资源时自动附带认证信息。攻击者正是利用这一特性,在用户浏览恶意网站时,诱导浏览器向目标网站发起携带合法 Cookie 的请求,从而完成伪造操作。
1.3 生活中的类比理解
为了更直观地理解 CSRF 攻击,我们可以用一个生活中的例子来类比:假设你拥有一张会员积分卡,这张卡可以在某家连锁店消费积分。正常情况下,只有你本人持卡才能使用积分。但如果有人偷偷复制了你的卡片,或者在你不知情的情况下拿走了你的卡,当这个人拿着卡去消费时,店员只认卡不认人,就会误以为是他本人在操作,从而允许使用你的积分完成交易。
在这个类比中,会员积分卡就相当于浏览器中存储的 Cookie,店员验证卡片的过程就如同服务器验证请求中的 Cookie,而偷卡消费的人则是发起 CSRF 攻击的恶意第三方。关键在于:服务器(店员)无法区分请求是用户本人主动发起的,还是被恶意网站诱导浏览器自动发送的。
二、CSRF 攻击的典型流程与技术细节
2.1 攻击场景还原
让我们通过一个完整的攻击流程来深入理解 CSRF 的运作机制:
第一步:用户正常登录目标网站
用户访问银行网站 A(例如 a-bank.com),输入用户名和密码完成登录。登录成功后,服务器生成会话 Cookie 并返回给浏览器,浏览器将其保存在本地。此后,用户在该网站的所有操作都会自动携带这个 Cookie,无需重复登录。
用户访问银行网站 A(例如 a-bank.com),输入用户名和密码完成登录。登录成功后,服务器生成会话 Cookie 并返回给浏览器,浏览器将其保存在本地。此后,用户在该网站的所有操作都会自动携带这个 Cookie,无需重复登录。
第二步:用户访问恶意网站
用户在未登出银行网站的情况下,打开了另一个网站 B(例如 b-malicious.com)。这个网站可能是一个被黑客控制的论坛、广告页面,甚至是看似正常的新闻网站,但其中嵌入了攻击者预先布置的恶意代码。
用户在未登出银行网站的情况下,打开了另一个网站 B(例如 b-malicious.com)。这个网站可能是一个被黑客控制的论坛、广告页面,甚至是看似正常的新闻网站,但其中嵌入了攻击者预先布置的恶意代码。
第三步:恶意代码触发伪造请求
恶意网站中包含一段精心构造的代码,例如一个尺寸为 0×0 像素的透明图片标签,其 src 属性指向银行网站的转账接口,并附带攻击者指定的收款账号和金额参数。由于图片尺寸为 0,用户在页面上完全看不到这个元素,但浏览器在解析 HTML 时,会像加载普通图片一样,自动向该 URL 发起 GET 请求。
恶意网站中包含一段精心构造的代码,例如一个尺寸为 0×0 像素的透明图片标签,其 src 属性指向银行网站的转账接口,并附带攻击者指定的收款账号和金额参数。由于图片尺寸为 0,用户在页面上完全看不到这个元素,但浏览器在解析 HTML 时,会像加载普通图片一样,自动向该 URL 发起 GET 请求。
第四步:请求携带合法凭证
关键点在于:浏览器在向 a-bank.com 发起请求时,会自动附带之前登录时获得的 Cookie。银行服务器收到请求后,验证 Cookie 有效,便认为这是用户本人发起的转账操作,于是执行转账逻辑,将指定金额转入攻击者控制的账户。
关键点在于:浏览器在向 a-bank.com 发起请求时,会自动附带之前登录时获得的 Cookie。银行服务器收到请求后,验证 Cookie 有效,便认为这是用户本人发起的转账操作,于是执行转账逻辑,将指定金额转入攻击者控制的账户。
第五步:攻击完成,用户毫不知情
整个过程可能在几毫秒内完成,用户既没有看到任何异常页面,也没有收到操作确认提示。直到事后查看账户余额或交易记录时,才发现资金已被转移。
整个过程可能在几毫秒内完成,用户既没有看到任何异常页面,也没有收到操作确认提示。直到事后查看账户余额或交易记录时,才发现资金已被转移。
2.2 攻击载体的多样性
上述示例使用的是图片标签发起 GET 请求,这只是 CSRF 攻击最基础的形式。实际上,攻击者可以采用多种技术手段来触发伪造请求:
- 表单自动提交:通过 JavaScript 在页面加载时自动提交一个隐藏的 POST 表单,这种方式可以携带更复杂的参数,且能绕过仅允许 POST 接口的防护。
- AJAX 请求:利用 XMLHttpRequest 或 Fetch API 发起异步请求,配合其他漏洞(如 CORS 配置不当)实现更隐蔽的攻击。
- 社交工程诱导:通过邮件、即时消息等渠道发送伪装成正常链接的恶意 URL,诱使用户主动点击,从而触发攻击。
- 结合 XSS 攻击:如果目标网站存在 XSS 漏洞,攻击者可以先注入恶意脚本,再利用该脚本发起 CSRF 请求,形成组合攻击,危害更大。
2.3 真实案例回顾
历史上曾发生过多起影响广泛的 CSRF 攻击事件。例如 2008 年,某知名社交网站曾因未对好友请求功能添加 CSRF 防护,导致攻击者可以批量诱导用户自动添加陌生人为好友,进而传播恶意内容。又如 2010 年,某电商平台因购物车结算接口缺乏令牌验证,被攻击者构造恶意页面,诱导已登录用户下单购买指定商品。
这些案例共同揭示了一个事实:只要网站的关键操作接口未对请求来源进行有效验证,就可能成为 CSRF 攻击的目标。尤其是涉及资金交易、个人信息修改、权限变更等高风险操作,更需要严格的防护机制。
三、CSRF 与 XSS 的区别与联系
在讨论防御策略之前,有必要厘清 CSRF 与另一种常见攻击 XSS 之间的关系,因为两者常被混淆,且在某些场景下会相互结合。
3.1 核心区别
- 攻击目标不同:XSS 攻击的目标是"窃取用户数据"或"劫持用户会话",攻击者通过注入恶意脚本,在用户浏览器中执行,从而获取 Cookie、键盘记录等敏感信息;而 CSRF 攻击的目标是"冒用用户身份执行操作",攻击者不直接获取用户数据,而是利用用户的登录状态完成非授权操作。
- 利用机制不同:XSS 依赖于目标网站对用户输入过滤不严,使恶意脚本得以存储或反射执行;CSRF 则依赖于浏览器自动携带 Cookie 的机制,以及目标网站未验证请求来源的缺陷。
- 防御思路不同:XSS 防御侧重于输入过滤、输出编码、内容安全策略(CSP)等;CSRF 防御则侧重于请求令牌、来源验证、Cookie 属性设置等。
3.2 潜在关联
尽管两者原理不同,但在实际攻击中可能形成组合拳。例如:攻击者先通过 XSS 漏洞窃取用户的 CSRF Token,再结合 CSRF 发起更精准的攻击;或者利用 CSRF 诱导用户访问含 XSS Payload 的页面,实现双重危害。因此,在实际开发中,应同时考虑两类攻击的防护措施,构建多层次的安全体系。
四、CSRF 攻击的系统化防御方案
针对 CSRF 攻击的特性,业界已形成一套较为成熟的防御体系。以下将从多个维度详细介绍主流防御方法,并分析其适用场景与局限性。
4.1 关键操作增加二次验证
对于涉及资金、隐私、权限变更等高风险操作,最直接有效的防御方式是增加额外的身份验证步骤。例如:
- 图形验证码:要求用户在提交敏感请求前输入图片中的字符,由于验证码具有时效性和一次性,攻击者难以预先获取或伪造。
- 短信/邮箱验证码:通过用户绑定的手机号或邮箱发送动态验证码,确保操作由本人确认。
- 生物特征验证:在支持的设备上,结合指纹、面部识别等生物特征进行二次确认。
这种方法的优点是安全性高,用户感知明确;缺点是会略微增加操作成本,可能影响用户体验。因此建议仅对真正高风险的操作启用,避免过度验证造成用户疲劳。
4.2 规范 HTTP 请求方法的使用
在 Web 开发中,HTTP 方法的选择不仅关乎语义规范,也直接影响安全性。根据 RESTful 设计原则,GET 请求应用于获取数据,不应产生副作用;而 POST、PUT、DELETE 等方法才用于修改服务器状态。
许多早期 CSRF 攻击之所以容易实现,正是因为目标网站使用 GET 请求处理转账、修改密码等敏感操作。由于浏览器加载图片、脚本、样式表等资源时会自动发起 GET 请求,攻击者只需构造一个包含恶意 URL 的标签即可触发攻击。
因此,基础防御原则是:所有会改变服务器状态的操作,必须使用 POST 或更高级的请求方法。虽然这不能完全杜绝 CSRF(攻击者仍可通过表单自动提交发起 POST 请求),但能显著提高攻击门槛,要求攻击者必须诱导用户执行"提交"动作,而非仅仅"访问"页面。
4.3 验证请求来源:Referer 与 Origin 头检查
HTTP 请求头中的 Referer(注意拼写历史原因)字段记录了发起请求的页面地址,Origin 字段则标识了请求的来源源(协议+域名+端口)。服务器可以通过检查这两个字段,判断请求是否来自合法的本站页面。
例如,银行网站 a-bank.com 在处理转账请求时,可以验证 Referer 是否以 https://a-bank.com/ 开头。如果来自其他域名,则拒绝处理。这种方法实现简单,对防御基础 CSRF 攻击有效。
但需注意其局限性:
- Referer 字段可由浏览器设置控制,部分隐私保护插件或企业代理可能移除该字段;
- 某些旧版本浏览器或特殊网络环境可能不发送 Referer;
- 高级攻击者可能通过其他漏洞(如 XSS)篡改请求头。
因此,Referer 检查适合作为辅助防御手段,不宜作为唯一防护机制。
4.4 核心方案:CSRF Token 机制
目前业界最主流、最可靠的 CSRF 防御方案是 CSRF Token(也称为同步令牌模式)。其核心思想是:为每个用户会话或每次请求生成一个随机、不可预测的令牌,要求客户端在提交敏感请求时必须携带该令牌,服务器端验证令牌有效后才执行操作。
工作流程如下:
- 用户访问包含表单的页面时,服务器生成一个唯一的 CSRF Token,并将其嵌入表单的隐藏字段中,同时将该 Token 与用户会话绑定存储在服务器端。
- 用户提交表单时,Token 随其他数据一并发送至服务器。
- 服务器收到请求后,从会话中取出预期的 Token,与请求中提交的 Token 进行比对。
- 若两者一致,说明请求来自合法页面,执行操作;若不一致或缺失,则拒绝请求。
关键设计要点:
- Token 必须具备足够的随机性和长度(建议至少 128 位),防止被暴力猜测;
- Token 应与用户会话绑定,避免跨用户重用;
- 每次请求生成新 Token(每次令牌模式)比每会话生成一个(会话令牌模式)更安全,但实现复杂度略高;
- Token 不仅可通过表单隐藏字段传递,也可通过自定义请求头(如 X-CSRF-Token)传递,尤其适用于 AJAX 请求。
该方案的优势在于:即使攻击者能诱导浏览器发起请求,也无法获取或预测合法的 Token(因为 Token 不在 Cookie 中自动携带,且受同源策略保护),从而有效阻断伪造请求。
4.5 浏览器级防护:SameSite Cookie 属性
随着浏览器安全能力的提升,一种更底层的防护机制被引入:SameSite Cookie 属性。该属性由服务器在设置 Cookie 时指定,用于控制浏览器在跨站请求时是否携带该 Cookie。
SameSite 支持三个取值:
- Strict:最严格模式,任何跨站请求(即请求来源与 Cookie 所属域名不同)都不携带 Cookie。这意味着即使用户点击了恶意链接,浏览器也不会附带认证信息,从根本上阻断 CSRF。但缺点是用户从外部链接进入网站时可能需要重新登录,影响体验。
- Lax:平衡模式,允许部分"安全"的跨站 GET 请求携带 Cookie(如通过链接导航),但阻止跨站的 POST、PUT 等修改类请求携带 Cookie。这在保障安全的同时,保留了较好的用户体验,是目前推荐的默认值。
- None:显式允许跨站携带 Cookie,但必须同时设置 Secure 属性(即仅通过 HTTPS 传输)。适用于需要跨站认证的场景,如第三方登录。
现代浏览器(Chrome 51+、Firefox 60+、Safari 12+ 等)均已支持 SameSite 属性。开发者可在后端设置 Cookie 时添加该属性,例如:
Set-Cookie: sessionid=abc123; SameSite=Lax; Secure; HttpOnly。需要注意的是,SameSite 是浏览器层面的防护,不能替代应用层的 CSRF Token 机制,尤其对于需要支持旧版浏览器或复杂跨站场景的应用,仍应结合多种方案使用。
4.6 其他辅助防护措施
- 自定义请求头验证:对于 AJAX 请求,可要求客户端在请求头中添加自定义字段(如 X-Requested-With: XMLHttpRequest),服务器验证该字段存在。由于浏览器同源策略限制,恶意网站无法通过普通表单提交设置自定义头,从而增加攻击难度。
- 缩短会话有效期:减少 Cookie 的存活时间,降低攻击窗口。结合"记住我"功能时,应使用独立的长效令牌,并与主会话分离管理。
- 关键操作确认页面:在执行高风险操作前,跳转到一个中间确认页,要求用户再次点击确认。虽然不能完全防御自动化攻击,但能增加攻击成本。
- 监控与告警:建立异常行为检测机制,如同一账户短时间内发起大量敏感操作、来自非常用地理位置的请求等,及时触发告警或二次验证。
五、不同技术栈中的 CSRF 防护实践
5.1 后端框架内置支持
主流 Web 开发框架大多已内置 CSRF 防护机制,开发者只需正确配置即可:
- Spring Security(Java):默认启用 CSRF 保护,通过 _csrf 参数或 X-CSRF-Token 头验证令牌。
- Django(Python):中间件自动为表单添加 csrf_token 字段,并通过装饰器保护视图。
- Laravel(PHP):VerifyCsrfToken 中间件自动处理令牌生成与验证。
- Express + csurf(Node.js):通过中间件生成和验证令牌。
使用框架时,务必阅读文档了解其 CSRF 机制,避免因误配置(如错误排除某些路由)导致防护失效。
5.2 前端框架的集成
现代前端框架(如 React、Vue、Angular)在发起 AJAX 请求时,需手动处理 CSRF Token 的传递。常见做法是:
- 页面加载时,从后端获取 Token(可通过 meta 标签或专用接口);
- 将 Token 存储在 JavaScript 变量或特定 Cookie 中;
- 在每次请求时,通过请求头或参数附带 Token。
例如,可将 Token 写入
<meta name="csrf-token" content="...">,前端通过 DOM 读取后,在 Axios 等请求库的拦截器中统一添加请求头。5.3 API 服务的特殊考量
对于纯 API 服务(如无状态 REST API),传统基于会话的 CSRF Token 可能不适用。此时可考虑:
- 使用基于令牌的身份认证(如 JWT),并将 Token 放在请求头而非 Cookie 中,避免浏览器自动携带;
- 要求所有写操作必须携带自定义认证头,利用浏览器同源策略阻止跨站伪造;
- 对于必须使用 Cookie 认证的场景,严格设置 SameSite 和 Secure 属性,并配合 Origin 验证。
六、测试与验证 CSRF 防护有效性
部署防护措施后,应通过测试确保其有效性:
- 手动测试:尝试构造不含 Token 或 Token 错误的请求,验证服务器是否拒绝;
- 自动化扫描:使用 OWASP ZAP、Burp Suite 等安全工具,检测接口是否存在 CSRF 漏洞;
- 渗透测试:模拟攻击者视角,尝试组合 XSS、钓鱼等手段绕过防护;
- 代码审计:检查所有状态变更接口是否都应用了防护逻辑,避免遗漏。
七、总结与最佳实践建议
CSRF 攻击利用的是用户身份认证机制与浏览器行为的"信任链",其危害在于用户完全不知情的情况下被冒用身份。防范 CSRF 没有银弹,需要多层次、纵深防御:
- 默认原则:所有状态变更操作必须使用 POST 及以上方法,禁止用 GET 处理敏感逻辑。
- 核心机制:为关键接口实施 CSRF Token 验证,确保令牌随机、一次性、与会话绑定。
- 浏览器协同:设置 Cookie 的 SameSite=Lax 或 Strict 属性,利用浏览器原生能力增强防护。
- 辅助验证:高风险操作增加二次验证,结合 Referer/Origin 检查作为补充。
- 框架利用:优先使用框架内置的 CSRF 防护,避免重复造轮子且降低出错概率。
- 持续监控:建立安全日志和异常检测机制,及时发现并响应潜在攻击。
- 用户教育:提醒用户操作完成后及时登出,避免在公共设备保存登录状态。
网络安全是一场持续的攻防对抗。随着技术发展,攻击手段不断演进,防御策略也需动态调整。作为开发者,我们不仅要掌握具体技术方案,更要树立"默认安全"的设计思维,在系统架构初期就将安全作为核心考量。作为普通用户,也应提高安全意识,谨慎点击不明链接,定期检查账户活动,共同构建更安全的网络环境。
通过本文的系统讲解,相信读者已对 CSRF 攻击的原理、危害及防御有了全面认识。在实际项目中,建议结合业务场景选择合适的防护组合,并定期进行安全评估,确保防护措施持续有效。唯有如此,才能在享受 Web 应用便利的同时,有效守护用户数据与系统安全。
你可能會有興趣的文章:


