新的无状态 JWT 认证理念!它真的安全吗?

Posted

技术标签:

【中文标题】新的无状态 JWT 认证理念!它真的安全吗?【英文标题】:New Stateless JWT Auth Idea! Is it actually safe? 【发布时间】:2020-10-11 12:14:43 【问题描述】:

我一直在为我的无状态应用程序的身份验证 API 处理 JWT,我非常喜欢 JWT 的工作方式,但是由于将 JWT 存储在本地存储中使其容易受到 XSS 攻击,这让我有点失望。不过,我认为如果您的应用程序受到 XSS 攻击,JWT 令牌可能是您最不关心的事情。另一方面,如果攻击者决定鬼鬼祟祟地专门窃取用户的 JWT,而您没有注意到,那将是最坏的情况。我知道你们每个人都对 JWT 的安全性有自己的看法,但我不是在这里讨论什么是最差的,什么是迄今为止最好的。

相反,我将谈论一个新想法,即充分利用 JWT 进行身份验证,可以这么说。顺便说一句,我不完全确定是否有人想过这个想法,但到目前为止我还没有读过类似的东西。如果你有,我很抱歉标题并告诉我该给谁学分。事不宜迟,让我们开始吧。

首先,我想让您知道,我们的令牌将使用较长的到期时间(例如 24 小时)并且将保持无状态,但问题是如果您的 JWT 被盗,任何人都可以使用它,对吧?因此,为了防止这个问题,我们需要让 JWT 对除真实用户之外的任何人都不可用。我们可以通过在登录时获取用户的 IP 地址(以及用户 ID 或您需要的其他内容)并将其存储在 JWT 有效负载中来实现这一点。然后,为了验证 JWT 是否安全,我们将检查 JWT 有效负载中的 IP 是否与发出请求的 IP 匹配。如果匹配,我们从 JWT 有效负载中提取用户 ID,然后将用户数据加载到我们的全局身份验证状态。因此,即使您的 JWT 以某种方式被盗,他们也无法将其与另一个 IP 一起使用,这使得您的 JWT IP 是特定的。此外,如果您想实现真正的注销功能,可以使用 Redis 保持无状态,同时能够撤销 JWT。

简而言之

使用凭据登录用户 获取发出请求的 IP 将 IP 放入 JWT 有效负载中(以及用户 ID 或您需要的其他内容) 返回 JWT 并将其存储在本地存储中

使用 JWT 自动登录;

检查本地存储中是否存在 JWT 如果存在,检查发出请求的 IP 是否与 JWT 负载中的 IP 匹配 如果匹配,则从 JWT 负载中提取用户 ID,以将用户数据加载到全局身份验证状态 完成!

【问题讨论】:

这不属于security.stackexchange.com吗? 【参考方案1】:
    这个问题之前已经讨论过很多次了。 当攻击者位于同一网络(企业、NAT)时,这不会阻止攻击。 这不适用于通常更改其 IP 地址的用户(移动到有线、在 wifi 网络之间等等)。 使用数据库(任何类型,例如 Redis)来存储注销状态并不是无状态的。

如果情况合适,它可能仍然有用(即,它可以缓解您的威胁模型中的某些威胁,而它可能无法缓解其他威胁),但到目前为止,它还不是解决此问题的通用解决方案。

【讨论】:

感谢您的评论!这解释了很多。我已经看到很多关于 JWT、Cookie、本地存储等的讨论......似乎没有人找到实现这一目标的好方法。有人说 Cookies 更加久经沙场,但并不现代。其他人说 JWT 不适合身份验证。 有一种方法可以将 JWT 放入 cookie 中,这样可以同时防止 CSRF 和 XSS 攻击。我认为这是迄今为止最好的方法。所以,我想知道你有什么建议? 默认情况下将 jwt 放入 cookie 不会阻止 csrf。您可以使用新的samesite cookie 属性,这会有所帮助,但较旧的浏览器不支持该属性。我认为 jwts 大多是不必要的,httponly cookie 中的普通旧会话 id 通常更好、更安全。 Jwt 可用于复杂的单点登录场景和其他一些情况(尤其是在需要真正的无状态时),但在没有真正了解其风险的情况下,它们被过度使用。

以上是关于新的无状态 JWT 认证理念!它真的安全吗?的主要内容,如果未能解决你的问题,请参考以下文章

一步步带你了解前后端分离利器之JWT

JWT 令牌中的无状态身份验证和权限

无状态后端安全吗?

为啥 JWT 是无状态认证?

JWT 用于无状态 API,但会话控制用于安全性

HTTP/2 是无状态协议吗?