为什么要将 CSRF 令牌放入 JWT 令牌中?
我想对 Stormpath 帖子,解释将 JWT 存储在 localStorage 或 cookie 中的优缺点.
I want to bring a doubt about JWT tokens and CSRF from the Stormpath post that explain the advantages and disadvantages of storing the JWT either in localStorage or cookies.
[...] 如果您使用 JS 从 cookie 中读取值,这意味着您无法在 cookie 上设置 Httponly 标志,所以现在您网站上的任何 JS可以读取它,从而使其具有与存储完全相同的安全级别localStorage 中的一些东西.
[...] if you are reading values out of a cookie using JS, that means you can't set the Httponly flag on the cookie, so now any JS on your site can read it, thus making it the exact same security-level as storing something in localStorage.
我试图了解他们为什么建议将 xsrfToken 添加到智威汤逊.不将您的 JWT 存储在 cookie 中然后将其提取并将 JWT 放在 HTTP 标头中并验证基于 HTTP 标头的请求完成与Angular 的 X-XSRF-TOKEN?没有其他域可以在如果您基于标头中的 JWT 进行身份验证,则代表用户,因为其他域无法从 cookie 中提取 JWT.我不了解 JWT 中 xsrfToken 的用途——也许它只是额外的防御层——这意味着攻击者必须您的网站上有一个受损的脚本,并且当时有一个用户 CSRF.所以他们必须以两种方式击中你才能发动攻击.
I'm trying to understand why they recommend adding the xsrfToken to the JWT. Doesn't storing your JWT in the cookie and then extracting it out and placing the JWT in the HTTP header and authenticating the request based on the HTTP header accomplish the same thing as Angular's X-XSRF-TOKEN? No other domain could make requests on a user's behalf if you authenticate based on the JWT in the header, since other domains cannot extract the JWT from the cookie. I don't understand the purpose of the xsrfToken in the JWT - perhaps its just an additional layer of defense - meaning that attackers would have to have a compromised script on your site and CSRF a user at the time. So they'd have to hit you in both ways to be able to pull of an attack.
帖子链接在这个答案中,其中说:
The post is linked in this answer where says:
最后一件事是确保您在每个节点上都有 CSRF 保护HTTP请求确保外部域发起请求您的网站无法运行.
The last thing is to ensure that you have CSRF protection on every HTTP request to ensure that external domains initiating requests to your site cannot function.
[...] 然后,在每个请求进入您的服务器时,确保您自己的JavaScript 代码读取 cookie 值并将其设置为自定义标题,例如X-CSRF-Token 并在每个请求中验证该值服务器.外部域客户端无法为除非外部客户端获得授权,否则向您的域发出请求通过 HTTP 选项请求,因此任何 CSRF 攻击尝试(例如一个 IFrame,无论如何)对他们来说会失败.
[...] Then, on every request into your server, ensure that your own JavaScript code reads the cookie value and sets this in a custom header, e.g. X-CSRF-Token and verify that value on every request in the server. External domain clients cannot set custom headers for requests to your domain unless the external client gets authorization via an HTTP Options request, so any attempt at a CSRF attack (e.g. in an IFrame, whatever) will fail for them.
即使他们可以设置自定义标头,他们也无法访问存储 JWT 令牌的 cookie,因为只有在同一域上运行的 JavaScript 才能读取 cookie.
Even if they could set custom headers, they couldn't access the cookie where the JWT token is stored because only JavaScript that runs on the same domain can read the cookie.
他们唯一的方法是通过 XSS,但是如果存在 XSS 漏洞,JWT 中的 xsrfToken 也会受到损害,因为在受信任的客户端域中运行的恶意脚本可以访问 cookie 中的 JWT 并在请求中包含标头使用 xsrfToken.
The only way they could is via XSS, but having an xsrfToken in the JWT is compromised too if exists XSS vulnerabilities because a malicious script running in the trusted client domain could access the JWT in the cookie and include a header in the request with the xsrfToken.
所以方程应该是:
- TLS + JWT 存储在安全 cookie + 请求标头中的 JWT + 无 XSS 漏洞.
如果客户端和服务器在不同的域中运行,服务器应该发送 JWT,客户端应该使用 JWT 创建 cookie.我认为这个等式在这种情况下仍然有效.
If the client and server are running in different domains, the server should send the JWT and the client should create the cookie with the JWT. I think that the equation is still valid for this situation.
更新: MvdD 同意我的看法:
由于浏览器不会自动将标头添加到您的请求中,它不易受到 CSRF 攻击
As the browser does not automatically add the header to your request, it is not vulnerable to a CSRF attack
推荐答案
我是 Stormpath 博客文章的作者.将 XSRF 令牌存储在 JWT 中并不是关于它在 JWT 中,而是关于它在 cookie 中.cookie 应该是 httpOnly,所以你不能从 Javascript 中读取它.
I am the author of the Stormpath Blog Post. Storing XSRF token in the JWT isn't about that it is in the JWT, it is about that it is in a cookie. The cookie should be httpOnly, so you can not read it from Javascript.
现在,我认为引起一点混乱的一点是我在谈论角度.Angular 也将它设置为只有 XSRF cookie(不是 httpOnly),以便在请求时将其放入标头中(只能由同一域上的 javascript 完成).这些不是同一个cookie.
Now, I think the point that caused a little confusion is where I talk about angular. Angular sets it's only XSRF cookie as well (which is not httpOnly) to put it into the header at request time (which can only be done by javascript on same domain). These are not the same cookie.
如果您考虑在您的应用程序中实现 XSRF 支持,这已经通过存储服务器端状态和存储 XSRF 的点来完成.将其存储在 httpOnly cookie 中意味着使用 XSRF 实现无状态.在这里,您将验证 JWT 签名,从声明中获取 XSRF,并将其与标头进行比较.
If you think about implementing XSRF support in your application, this has been done with storing server side state and the point of storing the XSRF. Storing it in the httpOnly cookie is about being stateless with XSRF. Here, you would validate the JWT signature, get the XSRF out of the claims, and compare it to the header.
您的问题的答案是您不需要在服务器上存储状态.
The answer to your question is so that you do not need to store state on your server.
相关文章