存储在 cookie 中的 JWT - 安全问题

Posted

技术标签:

【中文标题】存储在 cookie 中的 JWT - 安全问题【英文标题】:JWT stored in cookie - security concerns 【发布时间】:2017-03-27 06:41:17 【问题描述】:

我正在使用基于 JWT 的身份验证构建带有服务器端渲染的 SPA 应用程序。

目前的实现是:

用户名和密码验证成功后,JWT 令牌发放并传输给客户端 然后将令牌存储在 cookie 中(不是 HttpOnly) - 这样做的目的是避免在完全刷新或关闭页面后再次登录 使用令牌注销已删除的 cookie Authorization 标头附加到每个 API 请求(如果存在令牌) 完整的 SSL 流量

由于服务器端渲染,我无法将令牌存储在 LocalStorage 中,也没有 HttpOnly 因为我需要访问 cookie 才能构造 Authorization 标头。

在这种架构中窃取令牌的可能性有哪些?

【问题讨论】:

【参考方案1】:

一个主要风险是应用程序中的任何单个跨站点脚本漏洞都可能被用来从 cookie 中窃取令牌,因为它不是 httpOnly(虽然我理解为什么会这样)。 XSS 在 SPA 等大量 javascript 应用程序中非常常见且难以避免。

您还说令牌保存在 cookie 中,以便在关闭浏览器后,用户仍处于登录状态。一方面,这是一种不好的做法,关闭浏览器的用户可能希望被注销。另一方面,这意味着 cookie 被持久化到磁盘上,因此攻击者更容易从客户端窃取它。

想到的另一件事是跨站点请求伪造(CSRF),但如果我理解正确的话,身份验证实际上是基于Authorize 标头,其中令牌被复制到每个请求中。如果是这种情况,CSRF 对您来说不是问题(但如果在 cookie 中发送令牌就足够了)。

所以至少,我认为你应该

不要为令牌使用持久化 cookie

尽量减少 XSS 的可能性(例如,通过自动扫描您的代码,但这永远不会 100%,也可以通过仔细选择默认安全技术)

确保身份验证基于 Authorize 标头而不是 cookie

仍然主要是因为 XSS 风险,我可能不建议在安全关键应用程序中这样做。

【讨论】:

事实上(如果我错了,请纠正我)令牌是通过 cookie 发送的(因为 cookie 存在,并且浏览器会自动发送它)在初始时,还没有 AJAX 请求,所以 CSRF 也是案子。 根据您的回答,我认为非常好的解决方案是将令牌存储在 HttpOnly cookie 中,然后在初始请求时读取它,将其保存在 Redux JS 存储(正在使用)中,然后使用Authorization 每个下一个 REST 请求的标头。据我了解,在初始问题中描述的架构的情况下,这里需要 CSRF 保护。你怎么看? 在这种情况下是的,如果您也使用 cookie 中的令牌,您还必须关心 CSRF。如果身份验证信息是由浏览器自动发送的,那么 CSRF 是一个问题,即。如果会话 ID 或令牌在 cookie 中。如果仅将请求标头用于身份验证,则无需进一步保护 CSRF 即可。我对 Redux 不是很熟悉,但是如果 cookie 是 httpOnly,你根本无法从 Javascript 访问它,所以你将无法用 Redux JS 存储它。将 JWT 存储在 httpOnly cookie 中会更安全,但用例会受到限制。

以上是关于存储在 cookie 中的 JWT - 安全问题的主要内容,如果未能解决你的问题,请参考以下文章

将 JWT 令牌存储在 cookie 中

安全性 - 本地存储与 Cookie

将 WebAPI JWT 访问令牌作为加密的 FormsAuthenticationTicket 存储在 Response.Cookies 中是不是安全(在 asp.net mvc 中)

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

如何在前端使用 HttpOnly jwt cookie

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