当前位置: 首页 > news >正文

CSRF 攻击:深入解析“借刀杀人“的请求伪造与防御之道

CSRF (Cross-Site Request Forgery),即跨站请求伪造,是一种极具欺骗性的网络攻击手段。它并非直接窃取用户数据,而是巧妙地"挟持"已认证用户的身份,在用户毫不知情的情况下,以用户的名义执行非预期的、甚至是恶意的操作。想象一下,您在网上银行刚刚完成了一笔交易,随后无意中点开了一个包含恶意代码的链接,结果您的账户可能就在您不知情的情况下向攻击者指定账户转了账——这就是 CSRF 攻击的典型场景。

一、CSRF 攻击是如何发生的?

CSRF 攻击的核心在于利用了 Web 应用对用户身份验证的信任机制,特别是基于 Cookie 的会话管理。

攻击流程详解 (以模拟银行转账为例):

  1. 用户登录受信任站点:用户 Alice 登录了她的网上银行 bank.com。登录成功后,bank.com 的服务器会在 Alice 的浏览器中设置一个包含会话信息的 Cookie,用于后续请求的身份认证。
  2. 诱导访问恶意站点/内容:Alice 在未登出 bank.com 的情况下,访问了一个由攻击者控制的恶意网站 evil.com,或者打开了一封包含恶意 HTML 内容的邮件,或者点击了一个论坛上的恶意链接。
  3. 恶意站点发起伪造请求evil.com 的页面中嵌入了指向 bank.com 的恶意请求。这个请求可能是一个<form>表单,通过 JavaScript 自动提交;或者是一个<img>标签,其src属性指向一个会触发敏感操作的 URL。
    例如,一个自动提交的表单可能如下:
    html <form id="csrf-form" action="https://bank.com/transfer" method="POST"> <input type="hidden" name="toAccount" value="attacker_account_number" /> <input type="hidden" name="amount" value="1000" /> </form> <script>document.getElementById('csrf-form').submit();</script> ‍
  4. 浏览器自动携带 Cookie:当浏览器从 evil.combank.com 发送这个伪造的转账请求时,由于同源策略的限制(准确说是 Cookie 的发送策略,默认情况下,向某个域发送请求时,浏览器会自动携带该域下的 Cookie),浏览器会自动将 bank.com 的有效会话 Cookie 一同发送过去。
  5. 受信任站点执行操作bank.com 的服务器收到请求后,检查到了合法的会话 Cookie,误认为这是 Alice 主动发起的合法操作,于是执行了转账指令。Alice 的资金因此被盗取,而她可能对此一无所知。

CSRF 攻击成功的关键前提:

  • 用户在受信任站点上保持登录状态(拥有有效的会话 Cookie)。
  • 用户在未登出受信任站点的情况下访问了恶意站点或内容。
  • 受信任站点没有针对 CSRF 的有效防护机制。

二、CSRF 攻击的防御策略

防御 CSRF 攻击的核心思想是:确保敏感操作的请求确实是由用户主动发起的,而不是第三方站点伪造的。以下是几种主要的防御方法:

1. Anti-CSRF Token (首选且最有效)

这是目前公认最可靠、最广泛使用的 CSRF 防御机制。

原理:

  1. Token 生成与分发:当用户访问一个包含表单或需要执行敏感操作的页面时,服务器为该用户的当前会话生成一个随机的、不可预测的、一次性的(或者至少是会话级别的)字符串,称为 Anti-CSRF Token (也叫 CSRF Token, Synchronizer Token, Nonce)。
  2. Token 嵌入请求:服务器将这个 Token 嵌入到需要防护的 HTML 表单中,通常作为一个隐藏字段。对于通过 AJAX 等方式发起的请求,可以将 Token 放在 HTTP 请求头中(如 X-CSRF-Token),或者作为请求参数。
    html <form action="/update-profile" method="POST"> <input type="hidden" name="_csrf_token" value=" randon_generated_token_for_this_session_and_form "> <!-- 其他表单字段 --> <button type="submit">更新资料</button> </form> ‍
  3. Token 验证:当用户提交表单或发起敏感操作请求时,服务器会从请求中提取这个 Token,并与用户会话中存储的(或服务器端为该表单生成的)Token 进行比较。
    • 如果 Token 缺失、无效或不匹配,服务器将拒绝该请求,认为它可能是 CSRF 攻击。
    • 如果 Token 验证通过,则正常处理请求。

为什么有效?

攻击者在伪造请求时,无法获取或预测这个随机生成的 Anti-CSRF Token (因为第三方站点无法读取用户在受信任站点页面中的 Token 内容,除非受信任站点本身存在 XSS 漏洞)。因此,伪造的请求中要么没有 Token,要么 Token 是错误的,从而被服务器识破。

实施要点:

  • Token 必须具有足够的随机性和不可预测性。
  • Token 应该与用户会话绑定。
  • 对于极其敏感的操作,可以考虑使用一次性 Token (即 Token 在使用一次后即失效)。
  • 确保 Token 的保密性,不要通过 URL 参数传递,除非有特殊场景且有其他保护措施。

2. 检查 HTTP Referer 头部

HTTP Referer 头部字段记录了当前请求是从哪个源 URL 跳转过来的。服务器可以通过检查 Referer 来判断请求是否来自合法的、预期的源站点。

原理:

如果一个对 bank.com/transfer 的请求,其 Referer 头部是 evil.com,那么服务器可以判定这是一个可疑的跨站请求,并予以拒绝。

局限性:

  • Referer 可被客户端控制或伪造:虽然浏览器会自动设置 Referer,但一些代理、防火墙或用户隐私设置可能会移除或修改 Referer。攻击者也可能通过某些技术手段(虽然有难度)伪造 Referer
  • 空 Referer 问题:用户直接在浏览器地址栏输入 URL、从 HTTPS 站点链接到 HTTP 站点、或使用某些浏览器隐私模式时,Referer 头部可能为空。如果策略过于严格,禁止所有空 Referer 的请求,可能会误伤正常用户。
  • 隐私考虑Referer 头部可能会泄露用户的浏览历史,因此部分用户或工具会主动禁用它。

因此,检查 Referer 通常作为一种辅助性的防御手段,或者用于对风险较低的操作进行初步过滤,不应作为 CSRF 防御的主要或唯一手段

SameSite 是一个较新的 Cookie 属性,旨在提供一种由浏览器层面实现的 CSRF 防御机制。

SameSite 属性的三个值:

  • Strict:完全禁止第三方 Cookie 发送。即只有当请求的站点与 Cookie 所属的站点完全一致 (same-site) 时,Cookie 才会被发送。这能非常有效地防御 CSRF,但可能影响某些依赖第三方 Cookie 的正常用户体验(例如,从其他网站链接跳转过来后,无法保持登录状态)。
  • Lax (许多现代浏览器的默认值):允许在用户从外部站点导航到目标站点时发送 Cookie (例如通过点击链接),但对于"不安全"的 HTTP 方法(如 POST、PUT、DELETE)的跨站请求,以及通过 <iframe><img> 等加载的跨站资源请求,则不会发送 Cookie。
  • None:允许 Cookie 在所有上下文中发送,包括第三方跨站请求。但前提是必须同时指定 Secure 属性 (即 Cookie 只能通过 HTTPS 发送),以防止中间人攻击窃取 Cookie。

如何帮助防御 CSRF?

将敏感操作相关的会话 Cookie 设置为 SameSite=LaxSameSite=Strict,可以大大减少 CSRF 攻击的风险,因为浏览器在处理来自恶意站点的伪造请求时,不会自动发送这些关键的 Cookie。

注意事项:

  • 需要较新版本的浏览器支持。
  • SameSite=Strict 可能会影响用户体验。
  • SameSite=Lax 是一个很好的平衡点,能防御大部分 CSRF 场景,同时对用户体验影响较小。

4. 敏感操作二次确认

对于非常关键的操作,如转账、修改密码、删除重要数据等,即使有上述防御机制,增加一步用户交互式的二次确认也是一个好习惯。

例如:

  • 输入支付密码
  • 短信验证码
  • 邮件确认链接
  • 基于时间的一次性密码 (TOTP)

这虽然不是直接防御 CSRF 请求本身,但它确保了即使用户被 CSRF 攻击,恶意操作也无法在用户无感知的情况下最终完成。

三、总结:多层防御,构建安全壁垒

CSRF 攻击是一种隐蔽且危害较大的 Web 安全漏洞。单一的防御措施可能存在局限性,因此推荐采用多层防御策略:

  • 首选并正确实施 Anti-CSRF Token 机制,这是防御 CSRF 的核心和最有效手段。
  • 合理利用 SameSite Cookie 属性,作为浏览器层面的增强防护。
  • 对于高风险操作,务必实施二次确认机制
  • 谨慎使用检查 Referer 作为辅助手段。

相关文章:

  • penEuler操作系统结合豆包测试github仓库8086-Emulator项目
  • 数据结构、刷leetcode返航版--二分5/7
  • C++ 的未来趋势与挑战:探索新边界
  • 【hot100】bug指南记录1
  • 在 Ubuntu 中配置 Samba 实现「特定用户可写,其他用户只读」的共享目录
  • Spring AI(1)—— 基本使用
  • MVCC机制
  • base64与图片的转换和预览
  • Selenium Web自动化测试学习笔记(二)--八大元素定位
  • 追踪大型语言模型的思想(下)(来自针对Claude的分析)
  • Yii2.0 模型规则(rules)详解
  • ntdll!CsrServerApiRoutine函数--csrsrv!CsrCallServerFromServer什么时候被调用?
  • 2025.05.07-华为机考第二题200分
  • 动态规划之花园
  • 高并发内存池(一):项目简介+定长内存池的实现
  • C25-数组应用及练习
  • iTwin 数据报表(只是简单的原型不代表实现)
  • 解决 TimeoutError: [WinError 10060] 在 FramePack项目中连接 Hugging Face 超时的问题
  • ​​阿里云服务器:数字世界的“基因剪刀”与未来实验室​
  • 联想Horizon 2系列电脑 参数
  • 宝妈称宝宝在粽子中吃出带血创可贴,来伊份:已内部排查
  • 《瞭望》周刊社原总编辑、党委书记姬斌逝世,享年67岁
  • 一生要出片的年轻人,买爆相机
  • 贵州省总工会正厅级副主席梁伟被查,曾任贵州省纪委副书记
  • “行人相撞案”现场视频公布,法院:表述不当造成误导
  • 广西百色通报:极端强对流天气致墙体倒塌,3人遇难7人受伤