> 技术文档 > 如果目标服务器允许通过 GET 请求执行敏感操作,那么使用 CSRF Token也没有用,因为使用 CSRF Token只是针对post请求提交表单用的,是吗?_get请求 csrf

如果目标服务器允许通过 GET 请求执行敏感操作,那么使用 CSRF Token也没有用,因为使用 CSRF Token只是针对post请求提交表单用的,是吗?_get请求 csrf

虽然 CSRF Token 通常用于保护 POST 请求,但它并不是只能用于 POST 请求。CSRF Token 的核心作用是验证请求的合法性,无论请求是通过 GET、POST 还是其他 HTTP 方法发起的,都可以使用 CSRF Token 来防止跨站请求伪造(CSRF)攻击。


1. 为什么 GET 请求不应该执行敏感操作

根据 HTTP 协议的设计原则:

  • GET 请求应该是幂等的:即多次执行相同的 GET 请求不会对服务器状态产生影响。
  • GET 请求不应修改资源:GET 请求通常用于获取数据,而不是创建、更新或删除资源。

如果目标服务器允许通过 GET 请求执行敏感操作(如转账、删除资源等),这是一种严重的安全漏洞。即使使用了 CSRF Token,也无法完全弥补这种设计缺陷。

示例:

// 错误的实现:通过 GET 请求执行转账操作Route::get(\'/transfer\', function (Request $request) { $amount = $request->query(\'amount\'); $to = $request->query(\'to\'); // 执行转账逻辑});

攻击者可以通过嵌入隐藏图片的方式触发恶意 GET 请求:

<img src=\"https://bank.com/transfer?amount=1000&to=attacker\" style=\"display:none;\">

2. CSRF Token 的作用

CSRF Token 的主要目的是验证请求是否由合法用户主动发起。它的工作原理如下:

  1. 生成 Token
    • 服务器在用户访问页面时生成一个唯一的 CSRF Token,并将其存储在用户的会话中。
  2. 嵌入页面
    • Token 被嵌入到表单或 JavaScript 中,随请求一起发送。
  3. 验证 Token
    • 服务器接收到请求后,检查请求中的 Token 是否与会话中的 Token 匹配。

示例:

// 正确的实现:通过 POST 请求执行转账操作,并验证 CSRF TokenRoute::post(\'/transfer\', function (Request $request) { if (! $request->session()->token() === $request->input(\'_token\')) { abort(403, \'Invalid CSRF token\'); } $amount = $request->input(\'amount\'); $to = $request->input(\'to\'); // 执行转账逻辑});

即使攻击者尝试通过隐藏图片或其他方式触发请求,由于缺少有效的 CSRF Token,请求会被拒绝。


3. CSRF Token 是否可以用于 GET 请求?

虽然 CSRF Token 通常用于保护 POST 请求,但它同样可以用于保护 GET 请求。例如:

// 使用 CSRF Token 验证 GET 请求Route::get(\'/transfer\', function (Request $request) { if (! $request->session()->token() === $request->query(\'_token\')) { abort(403, \'Invalid CSRF token\'); } $amount = $request->query(\'amount\'); $to = $request->query(\'to\'); // 执行转账逻辑});

在这种情况下,攻击者无法通过简单的链接或隐藏图片触发请求,因为请求中必须包含有效的 CSRF Token。

然而,这种方法并不推荐,原因如下:

  1. 违反 HTTP 协议的设计原则:GET 请求不应修改资源。
  2. Token 泄露风险:GET 请求的参数会出现在 URL 中,容易被记录在浏览器历史记录、服务器日志或第三方服务中,增加 Token 泄露的风险。

4. 如果目标服务器允许通过 GET 请求执行敏感操作,CSRF Token 是否有用?

在这种情况下,CSRF Token 的作用有限,但并非完全没有用。以下是两种可能的情况:

(1) 没有使用 CSRF Token

如果服务器没有使用 CSRF Token 或其他防护机制,攻击者可以通过隐藏图片或链接轻松触发恶意 GET 请求。例如:

<img src=\"https://bank.com/transfer?amount=1000&to=attacker\" style=\"display:none;\">

这种情况下,服务器完全无法区分合法请求和恶意请求。

(2) 使用了 CSRF Token

如果服务器要求 GET 请求中包含有效的 CSRF Token,攻击者需要知道用户的 Token 才能构造恶意请求。例如:

<img src=\"https://bank.com/transfer?amount=1000&to=attacker&_token=USER_TOKEN\" style=\"display:none;\">

由于 Token 是动态生成的且与用户会话绑定,攻击者很难获取到有效的 Token,从而降低了攻击的成功率。


5. 最佳实践

为了有效防止 CSRF 攻击,建议采取以下措施:

  1. 避免通过 GET 请求执行敏感操作
    • 敏感操作应使用 POST、PUT、DELETE 等方法。
  2. 使用 CSRF Token
    • 在所有非幂等请求中嵌入并验证 CSRF Token。
  3. 验证请求来源
    • 检查 RefererOrigin 头,确保请求来自合法页面。
  4. 配置 SameSite Cookie
    • 设置 Cookie 的 SameSite 属性为 StrictLax,防止跨站请求携带 Cookie。
  5. 实现双重验证
    • 对于高风险操作(如转账),要求用户重新输入密码或验证码。

6. 总结

  • CSRF Token 不仅适用于 POST 请求:它可以用于保护任何类型的请求,包括 GET 请求。
  • GET 请求不应执行敏感操作:这是 HTTP 协议的基本原则,违反这一原则会导致安全漏洞。
  • 使用 CSRF Token 可以增强安全性:即使目标服务器允许通过 GET 请求执行敏感操作,CSRF Token 仍然可以降低攻击的成功率,但并不能完全弥补设计缺陷。

因此,最安全的做法是避免通过 GET 请求执行敏感操作,并结合 CSRF Token 和其他防护机制来构建安全的 Web 应用程序。