首页 > 解决方案 > javascript 客户端设置 CSRF 令牌是否不安全?

问题描述

在我看来,CSRF 的主要目标是确认发出请求的客户端是我们期望的客户端。

我经常看到的解决方案是:

  1. 服务器生成随机 CSRF Token
  2. 服务器在 cookie 中设置 CSRF 令牌
    1. 服务器在生成表单时将 CSRF 令牌注入表单或
    2. 服务器将 CSRF 令牌传递给 javascript,并且 javascript 将 CSRF 令牌作为 XMLHTTPRequests 上的标头注入
  3. 收到请求时,通过检查 cookie 中的 CSRF 令牌是否与标头/表单值中的 CSRF 令牌匹配来验证请求。

服务器为 (3)(1) 生成 CSRF 对我来说很有意义,但我无法想出为什么 (3)(2) 需要它的原因。

相反,如果客户端是纯 javascript,我相信这是安全的:

  1. Javascript 生成随机 CSRF 令牌
  2. Javascript 在 cookie 中设置 CSRF 令牌
  3. Javascript 在发出 XMLHTTPRequest 时在标头中传递 CSRF 令牌
  4. 服务器检查标头和 cookie 中的 CSRF 令牌是否匹配

我的理解是 3 和 4 都是攻击者不能做的事情,所以这也足以阻止攻击。那是对的吗?

如果那安全的,我们甚至需要执行步骤(1)和(2)吗?由于同源策略(假设 cors 配置正确),这是否也是安全的?

  1. Javascript 在 XMLHTTPRequest 中设置一个 'CSRF-Safe: true' 标头
  2. 服务器检查标头 CSRF-Safe 是否存在并设置为“true”

标签: javascriptsecuritycsrfwebsecurity

解决方案


是的,在 CORS 和同源策略存在的情况下,这两种简化方法都应该是安全的。CSRF-Safe: true事实上,只要您验证内容类型,您甚至不需要标题。

维基百科确认

如果数据以任何其他格式(JSON、XML)发送,标准方法是使用 XMLHttpRequest 发出 POST 请求,并通过 SOP 和 CORS 阻止 CSRF 攻击;有一种技术可以使用 ENCTYPE 属性从简单的 HTML 表单发送任意内容;这样的虚假请求可以通过 text/plain 内容类型与合法请求区分开来,但如果服务器上没有强制执行,则可以执行 CSRF[12][13]


推荐阅读