为什么在身份验证期间使用JWT刷新令牌可以防止CSRF ?



我已经阅读了一些关于JWT刷新令牌以及如何/为什么使用它们的文章。有一件事我在这里看到过:https://hasura.io/blog/best-practices-of-using-jwt-with-graphql/#persistance和https://dev.to/cotter/localstorage-vs-cookies-all-you-need-to-know-about-storing-jwt-tokens-securely-in-the-front-end-15id

是使用刷新令牌可以减轻CSRF攻击。第一篇文章说:

刷新令牌由认证服务器作为HttpOnly cookie发送给客户端,并由浏览器在/refresh_token API调用中自动发送。由于客户端Javascript无法读取或窃取HttpOnly cookie,因此在减轻XSS方面,这比将其作为普通cookie或在本地存储中持久化要好一些。这种方法也可以避免CSRF攻击,因为即使表单提交攻击可以进行/refresh_token API调用,攻击者也无法获得返回的新JWT令牌值。

第二篇文章也说了类似的话:

虽然提交给/refresh_token的表单可以工作,并且会返回一个新的访问令牌,但是如果攻击者使用HTML表单,则无法读取响应

我正在努力了解这将如何防止CSRF攻击,因为我正在思考以下内容:

  1. 从另一个域到用户的/refresh token请求将返回新的JWT令牌给用户。我将假设这是存储在HttpOnly cookie(如在第一篇文章中所做的)
  2. 由于CSRF不涉及任何javascript注入和httpOnly的cookie,因此攻击者无法读取新JWT令牌的值。但是,如果JWT令牌再次存储在cookie中,那么CSRF攻击者肯定可以使用这个新的cookie发送另一个请求,并使用新的JWT令牌。

如果我的理解是正确的,我正在努力了解如何通过使用刷新令牌来防止CSRF攻击。谁能解释一下为什么刷新令牌可以防止CSRF攻击,为什么CSRF攻击者不能使用用户将收到的新JWT来进行未来的攻击?

在我看来,真正防止CSRF攻击的方法是使用相同的esite cookie,或者使用某种防伪令牌。

新的jwt不会作为cookie从标识提供者返回。这将没有多大意义,因为不同来源的客户端将无法读取它。相反,令牌在响应体中传递,甚至在url中传递(在这种情况下通常不是令牌,但我们不要深入研究它)。

所以idp有它的httpOnly cookie来对用户进行身份验证,以某种不是cookie的方式发出一个新的令牌,客户机将适当的源(而不是idp)的令牌存储在localstorage中。这样,对资源服务器的任何调用都不会受到csrf的攻击,因为需要从本地存储显式地添加令牌。idp可以被attacker.com调用来发出一个新的令牌("csrf"),但是由于同源策略,attacker.com将无法访问该令牌,因此它是不可利用的。

请注意,即使新的令牌作为cookie返回给idp并由客户端从中读取,它仍然是可以的,因为idp不会对该令牌执行任何操作,并且资源服务器(~api)不会自动接收它。

最新更新