为啥将刷新令牌存储在仅 HTTP 的 Cookie 中以防止 CSRF 攻击?

Posted

技术标签:

【中文标题】为啥将刷新令牌存储在仅 HTTP 的 Cookie 中以防止 CSRF 攻击?【英文标题】:Why store Refresh Token in a HTTP Only Cookie Prevent From CSRF Attack?为什么将刷新令牌存储在仅 HTTP 的 Cookie 中以防止 CSRF 攻击? 【发布时间】:2021-08-11 18:17:52 【问题描述】:

我刚刚读到这篇文章

https://hasura.io/blog/best-practices-of-using-jwt-with-graphql/

总而言之,他们建议将 JWT 访问令牌存储在内存中(例如作为 javascript 中的变量),并将刷新令牌存储在 HTTP-Only Cookie 中。

他们说:

但是通过刷新令牌间接保持我们的会话,我们 防止我们使用 JWT 会遇到的直接 CSRF 漏洞 令牌。

但它是否将 Refresh Token 存储在 HTTP-Only cookie 中仍然容易受到 CSRF 攻击?例如, evilsite.com 可以向 /refreshtoken 端点发出请求以获取新的 JWT 访问令牌。我对 HTTP-Only cookie 的理解是无法从 JavaScript 读取 cookie,但每当发出 HTTP 请求时,它都会自动发送,就像 evilsite.com 所做的那样。 (如果我错了,请纠正我)。

【问题讨论】:

【参考方案1】:

如果谨慎使用,cookie 中的刷新令牌和内存中的访问令牌可能是一个很好的模型。希望在BFF-TMI等标准中提供一些更好的指导。

cookie 应该具有这些属性,而 SameSite 属性意味着 evilsite 无法发送它,因此从 CSRF 的角度来看它是好的。

仅 HTTP 安全 AES256 加密 SameSite=strict

OWASP 的CSRF Guidance 似乎建议同时使用 SameSite 和 CSRF 令牌作为首选选项。

我感兴趣的是我目前如何在 SPA 代码示例中实现一些东西 - 以防从以下方面借鉴想法有用:

SPA OAuth Code Back End API OAuth Code

随着该领域指导的发展,我可能会稍微改变主意。

高安全性选项?

目前的共识是,在安全性方面,以下选项是首选,但我希望来年风险和缓解措施能够得到更好的记录:

将访问令牌完全排除在浏览器之外 通过“后端为前端”代理所有 API 调用 看到这个有见地的2021 video

不过,此选项可能会在某些领域增加复杂性,并且在某些情况下也可能会限制功能。

与安全性通常一样,需要权衡其他因素,选择的解决方案可能取决于数据敏感性和利益相关者关心的内容。

【讨论】:

以上是关于为啥将刷新令牌存储在仅 HTTP 的 Cookie 中以防止 CSRF 攻击?的主要内容,如果未能解决你的问题,请参考以下文章

JWT 刷新和访问令牌

为啥不将 JWT 访问令牌存储在内存中并在 cookie 中刷新令牌?

IdentityServer4 - 刷新令牌混合流程 - Cookie 和存储

Java Angular JWT 实现

带有存储在 cookie 中的刷新令牌的 SPA - 如何使用 IdentityServer4 进行配置?

在 cookie 中存储访问令牌和刷新令牌