跨站请求伪造(CSRF)的底层原理、攻击场景与防御策略详解
字数 2307 2025-12-06 08:07:16

跨站请求伪造(CSRF)的底层原理、攻击场景与防御策略详解


1. 描述
跨站请求伪造(CSRF)是一种恶意攻击手段,攻击者诱使已登录用户在不知情的情况下,向当前已登录的 Web 应用发送一个恶意请求,从而执行未经授权的操作(例如转账、修改密码、发表评论等)。攻击的核心在于滥用浏览器在用户访问网站时自动附带认证凭证(如 Cookie、Session)的机制。它与 XSS 不同,XSS 是利用用户对网站的信任,而 CSRF 是利用网站对用户浏览器的信任。


2. 知识背景铺垫
要理解 CSRF,需明确以下机制:

  • 浏览器同源策略:限制来自 A 源的脚本访问 B 源的数据,但对发送请求的限制较松。例如,通过 <img><form> 等标签向任意源发起 GET/POST 请求是被允许的。
  • Cookie 自动携带:浏览器在向某域名发送请求时,会自动附带上该域名下的 Cookie(包括 Session Cookie),无论请求来源是用户主动点击还是页面中的隐藏请求。
  • 认证机制依赖:许多 Web 应用仅依赖 Cookie/Session 来验证用户身份,如果请求携带有效 Session Cookie,服务器就认为是合法用户的操作。

3. 攻击原理详解
攻击分为三个步骤:

  1. 用户登录目标网站:用户通过认证,在浏览器中保存了网站的 Session Cookie。
  2. 用户访问恶意网站:攻击者诱使用户访问包含恶意代码的第三方网站(如通过邮件链接、论坛图片等)。
  3. 自动发起伪造请求:恶意网站中隐藏了一个自动向目标网站发起请求的代码,浏览器会自动携带目标网站的 Cookie,请求在用户不知情下被执行。

4. 攻击场景与代码示例
假设目标网站 bank.com 有一个转账接口:

POST /transfer HTTP/1.1  
Host: bank.com  
Content-Type: application/x-www-form-urlencoded  

to_account=attacker&amount=1000

攻击者构造一个恶意页面,用户访问时会自动提交表单:

<!-- 恶意网站页面 -->
<form id="csrf-form" action="https://bank.com/transfer" method="POST">
  <input type="hidden" name="to_account" value="attacker">
  <input type="hidden" name="amount" value="1000">
</form>
<script>
  document.getElementById('csrf-form').submit();
</script>

若用户已登录 bank.com,浏览器会自动带上该站点的 Cookie,服务器认为这是合法请求,完成转账。


5. 关键攻击条件

  • 目标网站使用 Cookie/Session 认证。
  • 目标网站接口没有足够的 CSRF 防护。
  • 用户已登录目标网站,且浏览器保存了有效 Cookie。
  • 用户访问了攻击者控制的页面。

6. 防御策略层层递进

6.1 验证请求来源(Referer/Origin 检查)
服务器检查 HTTP 头中的 RefererOrigin 字段,确保请求来自同源域名。

  • 优点:简单易实现。
  • 缺点:某些浏览器可能不发送这些头,或用户可以禁用;如果网站允许来自其他可信域名的请求,则需要维护白名单。

6.2 使用 CSRF Token
这是最主流的防御方案,步骤如下:

  1. 用户访问页面时,服务器生成一个随机、不可预测的 Token(如加密的随机字符串),存储在服务端 Session 或加密的 Cookie 中,并同时嵌入到页面的表单(或 Meta 标签)中。
  2. 当用户提交表单时,必须将该 Token 通过请求体(POST 参数)或请求头(X-CSRF-Token)发送到服务器。
  3. 服务器验证请求中的 Token 是否与 Session/Cookie 中存储的一致,不一致则拒绝请求。

为什么能防御:恶意网站无法获取 Token 值(受同源策略保护),因此无法构造包含有效 Token 的请求。

6.3 双重 Cookie 验证
将 Token 放在 Cookie 中,同时要求请求时从 Cookie 中读取 Token 并作为请求参数或请求头再次发送。服务器比较两者是否一致。

  • 优点:无需在服务端存储 Token,实现简单。
  • 缺点:如果网站存在 XSS 漏洞,可能被攻击者读取 Cookie 中的 Token;需注意 Cookie 作用域设置。

6.4 SameSite Cookie 属性
设置 Cookie 的 SameSite 属性,限制 Cookie 在跨站请求时不被发送。

  • SameSite=Strict:完全禁止跨站携带 Cookie。
  • SameSite=Lax:允许部分安全跨站请求(如顶级导航)携带 Cookie。
  • 优点:现代浏览器默认支持,防御效果显著。
  • 缺点:兼容性需考虑(旧浏览器可能不支持),且仅能防御 Cookie 层面的 CSRF。

6.5 增加二次验证
对敏感操作(如转账、改密)要求用户进行二次验证(密码、短信验证码、生物识别)。

  • 优点:安全性高。
  • 缺点:用户体验下降。

7. 最佳实践与注意点

  • 组合防御:采用 CSRF Token + SameSite Cookie 是最佳实践。
  • 敏感操作使用 POST:但仅用 POST 不够,因为攻击者仍可通过构造表单发起 POST 请求。
  • 注意 Token 存储与传输安全:Token 应足够随机、绑定用户 Session、每次会话或请求更新。
  • 防范 BREACH 攻击:避免 Token 在压缩响应中泄露。
  • API 额外防护:对于前后端分离项目,可将 Token 放在请求头中,避免放在 URL 中导致泄露。

8. 总结
CSRF 攻击利用的是“网站对用户浏览器的信任”,防御的核心思路是让攻击者无法伪造包含验证信息的完整请求。现代 Web 开发中,通过框架内置的 CSRF 防护(如 Django、Spring Security、Laravel 等)可轻松实现 Token 机制,配合 SameSite Cookie 可有效消除大部分 CSRF 风险。开发者应理解底层原理,避免在自定义场景中错误配置。

跨站请求伪造(CSRF)的底层原理、攻击场景与防御策略详解 1. 描述 跨站请求伪造(CSRF)是一种恶意攻击手段,攻击者诱使已登录用户在不知情的情况下,向当前已登录的 Web 应用发送一个恶意请求,从而执行未经授权的操作(例如转账、修改密码、发表评论等)。攻击的核心在于 滥用浏览器在用户访问网站时自动附带认证凭证(如 Cookie、Session)的机制 。它与 XSS 不同,XSS 是利用用户对网站的信任,而 CSRF 是利用网站对用户浏览器的信任。 2. 知识背景铺垫 要理解 CSRF,需明确以下机制: 浏览器同源策略 :限制来自 A 源的脚本访问 B 源的数据,但对 发送请求 的限制较松。例如,通过 <img> 、 <form> 等标签向任意源发起 GET/POST 请求是被允许的。 Cookie 自动携带 :浏览器在向某域名发送请求时,会自动附带上该域名下的 Cookie(包括 Session Cookie),无论请求来源是用户主动点击还是页面中的隐藏请求。 认证机制依赖 :许多 Web 应用仅依赖 Cookie/Session 来验证用户身份,如果请求携带有效 Session Cookie,服务器就认为是合法用户的操作。 3. 攻击原理详解 攻击分为三个步骤: 用户登录目标网站 :用户通过认证,在浏览器中保存了网站的 Session Cookie。 用户访问恶意网站 :攻击者诱使用户访问包含恶意代码的第三方网站(如通过邮件链接、论坛图片等)。 自动发起伪造请求 :恶意网站中隐藏了一个自动向目标网站发起请求的代码,浏览器会 自动携带目标网站的 Cookie ,请求在用户不知情下被执行。 4. 攻击场景与代码示例 假设目标网站 bank.com 有一个转账接口: 攻击者构造一个恶意页面,用户访问时会自动提交表单: 若用户已登录 bank.com ,浏览器会自动带上该站点的 Cookie,服务器认为这是合法请求,完成转账。 5. 关键攻击条件 目标网站使用 Cookie/Session 认证。 目标网站接口没有足够的 CSRF 防护。 用户已登录目标网站,且浏览器保存了有效 Cookie。 用户访问了攻击者控制的页面。 6. 防御策略层层递进 6.1 验证请求来源(Referer/Origin 检查) 服务器检查 HTTP 头中的 Referer 或 Origin 字段,确保请求来自同源域名。 优点:简单易实现。 缺点:某些浏览器可能不发送这些头,或用户可以禁用;如果网站允许来自其他可信域名的请求,则需要维护白名单。 6.2 使用 CSRF Token 这是 最主流 的防御方案,步骤如下: 用户访问页面时,服务器生成一个随机、不可预测的 Token(如加密的随机字符串),存储在服务端 Session 或加密的 Cookie 中,并同时嵌入到页面的表单(或 Meta 标签)中。 当用户提交表单时,必须将该 Token 通过请求体(POST 参数)或请求头(X-CSRF-Token)发送到服务器。 服务器验证请求中的 Token 是否与 Session/Cookie 中存储的一致,不一致则拒绝请求。 为什么能防御 :恶意网站无法获取 Token 值(受同源策略保护),因此无法构造包含有效 Token 的请求。 6.3 双重 Cookie 验证 将 Token 放在 Cookie 中,同时要求请求时从 Cookie 中读取 Token 并作为请求参数或请求头再次发送。服务器比较两者是否一致。 优点:无需在服务端存储 Token,实现简单。 缺点:如果网站存在 XSS 漏洞,可能被攻击者读取 Cookie 中的 Token;需注意 Cookie 作用域设置。 6.4 SameSite Cookie 属性 设置 Cookie 的 SameSite 属性,限制 Cookie 在跨站请求时不被发送。 SameSite=Strict :完全禁止跨站携带 Cookie。 SameSite=Lax :允许部分安全跨站请求(如顶级导航)携带 Cookie。 优点:现代浏览器默认支持,防御效果显著。 缺点:兼容性需考虑(旧浏览器可能不支持),且仅能防御 Cookie 层面的 CSRF。 6.5 增加二次验证 对敏感操作(如转账、改密)要求用户进行二次验证(密码、短信验证码、生物识别)。 优点:安全性高。 缺点:用户体验下降。 7. 最佳实践与注意点 组合防御 :采用 CSRF Token + SameSite Cookie 是最佳实践。 敏感操作使用 POST :但仅用 POST 不够,因为攻击者仍可通过构造表单发起 POST 请求。 注意 Token 存储与传输安全 :Token 应足够随机、绑定用户 Session、每次会话或请求更新。 防范 BREACH 攻击 :避免 Token 在压缩响应中泄露。 API 额外防护 :对于前后端分离项目,可将 Token 放在请求头中,避免放在 URL 中导致泄露。 8. 总结 CSRF 攻击利用的是“网站对用户浏览器的信任”,防御的核心思路是 让攻击者无法伪造包含验证信息的完整请求 。现代 Web 开发中,通过框架内置的 CSRF 防护(如 Django、Spring Security、Laravel 等)可轻松实现 Token 机制,配合 SameSite Cookie 可有效消除大部分 CSRF 风险。开发者应理解底层原理,避免在自定义场景中错误配置。