什么是 CSRF?

CSRF(Cross-Site Request Forgery,跨站请求伪造)是一种利用用户已登录身份,诱导其在不知情的情况下向受信任网站发送恶意请求的攻击方式。攻击者通过构造特定的请求,借助用户的浏览器自动携带的认证信息(如 Cookie),使服务器误以为是用户的合法操作,从而执行非授权的敏感操作。

攻击原理

CSRF 攻击的核心在于:

  • 身份伪造:攻击者无法直接获取用户的认证信息,但可以诱导用户的浏览器发送携带认证信息的请求。
  • 跨站请求:攻击者在其控制的站点上嵌入指向受信任站点的请求,当用户访问攻击者站点时,浏览器会自动发送这些请求。
  • 服务器信任:服务器根据请求中的认证信息(如 Cookie)判断请求的合法性,而不验证请求的来源,从而执行了攻击者构造的操作。

攻击流程

  1. 用户登录受信任网站(如 bank.com),浏览器保存了会话 Cookie。
  2. 用户在未登出 bank.com 的情况下,访问了攻击者控制的恶意网站。
  3. 恶意网站向 bank.com 发送伪造请求(如转账),浏览器自动附带 Cookie。
  4. bank.com 接收到请求,验证 Cookie 合法,执行了转账操作。

真实案例分析

WordPress CSRF 漏洞(2012)

攻击者利用 WordPress 3.3.1 版本中的 CSRF 漏洞,诱导管理员用户点击恶意链接,从而添加具有管理员权限的用户,篡改站点设置。美团技术

YouTube CSRF 漏洞(2008)

攻击者通过构造特定的请求,使用户在不知情的情况下将视频添加到“Favorites”,甚至发送消息、添加好友,导致用户隐私泄露和内容操控。美团技术

防御策略

1. 使用 CSRF Token(同步令牌)

在每次表单提交时,服务器生成一个唯一的 CSRF Token,并将其嵌入到表单中。服务器在接收到请求时,验证 Token 的有效性,确保请求来源合法。

实现示例(PHP)

// 生成 CSRF Token
function generate_csrf_token() {
   $token = bin2hex(random_bytes(32));
   $_SESSION['csrf_token'] = $token;
   return $token;
}

// 验证 CSRF Token
function verify_csrf_token($token) {
   return isset($_SESSION['csrf_token']) && hash_equals($_SESSION['csrf_token'], $token);
}

攻击者无法获取有效的 Token,从而防止 CSRF 攻击。

2. 设置 SameSite Cookie 属性

通过设置 Cookie 的 SameSite 属性,限制浏览器在跨站请求中发送 Cookie,从而降低 CSRF 风险。

  • Strict:Cookie 仅在同站请求中发送,最严格的设置。
  • Lax:Cookie 在大多数跨站请求中不会被发送,但在用户导航到目标网站的跨站请求中发送。
  • None:Cookie 在所有请求中发送,包括跨站请求。必须设置 Secure 属性。

设置示例(HTTP Header)

Set-Cookie: sessionid=abc123; SameSite=Strict; Secure; HttpOnly

现代浏览器已广泛支持 SameSite 属性,推荐结合使用 SecureHttpOnly 属性,增强 Cookie 的安全性。

3. 验证 Referer 或 Origin 头

服务器在处理敏感请求时,检查请求头中的 Referer 或 Origin 字段,确保请求来源于受信任的域名。

注意事项

  • Referer 头可能被用户禁用或伪造,不应作为唯一的防护手段。
  • Origin 头在跨站请求中更可靠,推荐优先使用。

4. 双重提交 Cookie

在 Cookie 和请求参数中同时发送相同的 Token,服务器验证两者是否一致。攻击者无法同时伪造 Cookie 和请求参数,从而防止 CSRF 攻击。

实现步骤

  1. 服务器在响应中设置一个 Cookie,包含 CSRF Token。
  2. 客户端在发送请求时,将该 Token 作为请求参数或自定义头部发送。
  3. 服务器验证请求中的 Token 与 Cookie 中的 Token 是否一致。

5. 使用验证码或双重认证(2FA)

对于敏感操作,要求用户输入验证码或进行双重认证(如短信验证码、硬件令牌),增加攻击难度。

优点

  • 即使攻击者伪造了请求,也无法通过额外的验证步骤。

缺点

  • 增加用户操作步骤,可能影响用户体验。

6. 限制请求方法

对于修改操作,使用 POST、PUT、DELETE 等请求方法,避免使用 GET 方法。攻击者难以在第三方网站中构造非 GET 请求,从而降低 CSRF 风险。

实现建议

  • 在服务器端配置中,禁止对敏感操作使用 GET 请求。
  • 在前端开发中,确保表单和 AJAX 请求使用正确的 HTTP 方法。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注