使用 AJAX GET 方法的 CSRF 令牌保护

Posted

技术标签:

【中文标题】使用 AJAX GET 方法的 CSRF 令牌保护【英文标题】:CSRF token protection with AJAX GET method 【发布时间】:2017-03-19 07:15:04 【问题描述】:

我对网上的信息有点困惑。

我在后端使用 Spring 安全性来使用 CSRF 保护。

我想问一下,当我使用 Ajax GET 方法在 HTTP 标头中传递令牌时,从我的 Angular 前端发送 CSRF 令牌是否安全?

因为根据 Spring 文档,我不应该使用 GET 方法,但另一方面,当我在 HTTP 标头中传递它时,它没有说明是否可以使用 GET Ajax。

第二,

如果我不应该使用 GET,我该如何使用 REST 服务和 CSRF 保护?我应该放弃 GET 方法还是 CSRF 保护?

【问题讨论】:

【参考方案1】:

由于 GET 请求不应该修改服务器上的任何状态并且应该是“只读”的,因此 GET 请求通常不需要 CSRF 保护。

泄漏问题主要与浏览器使用有关,因为 GET 请求通常不包含正文,因此令牌作为请求参数发送。因此,CSRF 令牌可以通过肩部冲浪可见、存储为书签、出现在浏览器历史记录中或登录到服务器(尽管日志记录也适用于 AJAX 请求)。

由于您谈论的是 AJAX 请求,因此大多数这种泄漏并不适用,尽管在标头中设置它可能有助于在 URL 出现在日志中的情况下,但日志也可能包含标头。

但实际上使用自定义标头(带或不带令牌)通常用于防止 CSRF 攻击,因为 AJAX 请求不能跨域设置自定义标头

接受 接受语言 内容-语言 上一个事件 ID 内容类型

因此使用像 X-Requested-With: XMLHttpRequest 这样的自定义标题,例如通过 jQuery 设置并在服务器上验证此 header 可以防止 CSRF 攻击。

最后但并非最不重要的一点是interesing article 关于 GET 和 POST 请求具有相同的令牌,并通过同源中的单独 Web 应用程序的 XSS 漏洞对 GET 请求进行同源访问,其中令牌可以从 GET 请求中泄漏并用于 POST。解决方案是不使用 CSRF 令牌进行 GET 或使用不同的令牌进行 GET 和 POST。

基本上关于您的问题,如果您的 GET 没有任何副作用,那么 CSRF 令牌并不是真正需要的,但不会造成伤害。另一方面,如果您的 GET 请求更改了服务器上的某些内容,您应该考虑使用另一个动词(例如 POST),具体取决于您想要做什么,然后使用 CSRF 令牌或自定义标头保护您的 POST 请求。

【讨论】:

以上是关于使用 AJAX GET 方法的 CSRF 令牌保护的主要内容,如果未能解决你的问题,请参考以下文章

在 ajax 提交时禁用 symfony 2 csrf 令牌保护

用于ajax调用的spring security csrf保护

禁用 Ajax 调用的 CSRF 保护 - 它有多糟糕?

公开会话的 CSRF 保护令牌是不是安全?

Ajax GET 请求后表单提交失败(无效的 CSRF 令牌)。怎么修?

Django ajax POST 扩展用于 CSRF 保护的 beforeSend 方法