为什么要在JWT令牌中放置CSRF令牌?

时间:2016-01-26 12:23:11

标签: javascript cookies csrf jwt owasp

我想对Stormpath post中的JWT令牌和CSRF提出疑问,这些令牌解释了将JWT存储在localStorage或cookies中的优缺点。

  

[...]如果您使用JS从cookie中读取值,那意味着您   无法在Cookie上设置Httponly标志,所以现在您的网站上有任何JS   可以读取它,从而使它与存储完全相同的安全级别   localStorage中的东西。

     

我试图了解他们为什么建议添加xsrfToken   JWT。不将JWT存储在cookie中然后将其解压缩   将JWT放在HTTP标头中并对其进行身份验证   基于HTTP头的请求完成同样的事情   Angular的X-XSRF-TOKEN?没有其他域可以在a上发出请求   代表用户,如果您根据标头中的JWT进行身份验证,   因为其他域无法从cookie中提取JWT。我没有   了解JWT中xsrfToken的用途 - 也许就是它的正义   另外一层防御 - 意味着攻击者必须这样做   您的网站上有一个受损的脚本,而CSRF则是当时的用户。所以   他们必须以两种方式击中你,以便能够进行攻击。

帖子链接在this answer,其中说:

  

最后一件事是确保每个人都有CSRF保护   HTTP请求,以确保外部域发起请求   您的网站无法正常运作。

     

[...]然后,在每次进入您的服务器的请求中,确保您自己的   JavaScript代码读取cookie值并在自定义中设置它   标题,例如X-CSRF-Token并验证每个请求的值   服务器。 外部域客户端无法为其设置自定义标头   请求到您的域,除非外部客户端获得授权   通过HTTP选项请求,所以任何CSRF攻击的尝试(例如,在   一个IFrame,无论如何都会失败。

即使他们可以设置自定义标头,他们也无法访问存储JWT令牌的Cookie,因为只有在同一域上运行的JavaScript才能读取Cookie。

他们唯一的方法是通过XSS,但如果存在XSS漏洞,JWT中的xsrfToken也会受到影响,因为在受信任的客户端域中运行的恶意脚本可以访问cookie中的JWT并在请求中包含一个标头使用xsrfToken。

所以等式应该是:

  • TLS + JWT存储在安全cookie + JWT请求标头中+没有XSS漏洞。

如果客户端和服务器在不同的域中运行,则服务器应发送JWT,客户端应使用JWT创建cookie。 我认为这个等式对这种情况仍然有效。

更新: MvdD agree with me

  

由于浏览器不会自动将标头添加到您的请求中,   它不容易受到CSRF攻击

2 个答案:

答案 0 :(得分:8)

我是Stormpath Blog Post的作者。在JWT中存储XSRF令牌并不是它在JWT中的存在,而是它在cookie中。 cookie应该是httpOnly,因此您无法从Javascript中读取它。

现在,我认为引起一点混乱的一点是我谈论角度的地方。 Angular设置它只是XSRF cookie(它不是httpOnly)在请求时将它放入标题(这只能通过同一域上的javascript完成)。这些不是相同的cookie。

如果您考虑在应用程序中实现XSRF支持,那么已经完成了存储服务器端状态和存储XSRF的点。将它存储在httpOnly cookie中是关于使用XSRF进行无状态处理。在这里,您将验证JWT签名,从索赔中获取XSRF,并将其与标题进行比较。

您的问题的答案是,您无需在服务器上存储状态。

答案 1 :(得分:4)

我的理解是:

  • 商店JWT是一个HTTPonly cookie。
  • 在该JWT中,存储散列版本的XSRF令牌。
  • 登录时向客户端发送XSRF令牌,以便将其存储在本地存储中
  • 稍后当客户端发送请求时,JWT会自动通过cookie发送每个请求,然后您还通过头或查询变量发送XSRF令牌,并在服务器端重新哈希以比较什么' s在服务器上的JWT中

您的JWT受到保护,不会在XSS中被盗,并且您可以免受XSRF的侵害。 XSS仍然可以在您的浏览器上执行,但只能在浏览器中对该会话造成损害。最终,你无法阻止某人编写一个只在浏览器上运行的非常详细的脚本,因此Web开发人员仍然需要传统的安全措施来保护XSS。