我想对JWT令牌和CSRF提出疑问,这来自于Stormpath的帖子,该帖子解释了在localStorage或cookie中存储JWT的优缺点。
如果您使用JS从cookie中读取值,这意味着您无法在cookie上设置Httponly标志,因此现在您站点上的任何JS都可以读取它,从而使其与将某些内容存储在localStorage中的安全级别完全相同。我正在尝试理解为什么他们建议将xsrfToken添加到JWT中。将JWT存储在cookie中,然后将其提取出来并将JWT放置在HTTP标头中,并基于HTTP标头对请求进行身份验证,是否能够实现与Angular的X-XSRF-TOKEN相同的效果?由于其他域无法从cookie中提取JWT,因此其他域不能代表用户发出请求。我不理解JWT中xsrfToken的目的 - 也许它只是额外的防御层 - 这意味着攻击者必须在您的站点上有一个受损的脚本并在那时对用户进行CSRF攻击。所以他们必须用两种方式打击您才能实施攻击。
该帖子链接在this answer中,其中说:
最后一步是确保每个HTTP请求都有CSRF保护,以确保外部域发起的请求无法正常工作。然后,在您的服务器的每个请求中,确保您自己的JavaScript代码读取Cookie值并在自定义标头(例如X-CSRF-Token)中设置该值,并验证服务器上的每个请求的该值。外部域客户端无法为向您的域发送的请求设置自定义标头,除非外部客户端通过HTTP Options请求获得授权,因此他们任何尝试CSRF攻击(例如在IFrame等)都将失败。即使他们可以设置自定义标头,他们也无法访问存储JWT令牌的Cookie,因为只有在相同域上运行的JavaScript才能读取Cookie。他们唯一的方式是通过XSS攻击,但如果存在XSS漏洞,则在JWT中包含xsrfToken也会受到威胁,因为在受信任的客户端域中运行的恶意脚本可以访问Cookie中的JWT并在请求中包括一个带有xsrfToken的标头。因此方程式应该是:TLS+ 存储在安全Cookie中的JWT + 请求头中的JWT + 没有XSS漏洞。
如果客户端和服务器在不同的域中运行,服务器应该发送JWT,客户端应该使用JWT创建cookie。我认为这种情况下方程仍然有效。
更新:MvdD同意我的观点:
由于浏览器不会自动添加头信息到您的请求中,因此它不易受到CSRF攻击。