JavaScript客户端设置CSRF令牌是否不安全?

时间:2019-07-03 01:33:03

标签: javascript security csrf websecurity

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

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

  1. 服务器生成随机CSRF令牌
  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”

1 个答案:

答案 0 :(得分:2)

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

维基百科confirms

  

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