JWT服务器的漏洞是否更具破坏性



更新:我已经结束了对这个问题的研究,并发布了一篇很长的博客文章来解释我的发现:JWT的未公开漏洞。我解释了如何大力推动使用JWT进行本地身份验证,却忽略了一个关键细节:签名密钥必须受到保护。我还解释说,除非你愿意竭尽全力保护密钥,否则最好通过Oauth委派身份验证,或者使用传统的会话ID。


我看过很多关于JSON Web令牌安全性的讨论——重放、撤销、数据透明、令牌指定的alg、令牌加密、XSS、CSRF——但我没有看到任何关于依赖签名密钥所带来的风险的评估。

如果有人破坏服务器并获得JWT签名密钥,在我看来,此人可以在此后使用该密钥伪造未过期的JWT并秘密获得访问权限。当然,服务器可以在每个请求中查找每个JWT来确认其有效性,但服务器完全使用JWT,因此不必这样做。服务器可以确认IP地址,但如果JWT不可信,这也需要查找,显然这样做无论如何都会妨碍可靠的移动访问。

将此与基于会话ID的服务器漏洞进行对比。如果该服务器正在对密码进行哈希处理,则攻击者必须在会话ID过期之前为每个用户单独获取并使用会话ID。如果服务器只存储会话ID的散列,攻击者将不得不向服务器写入以确保访问。无论如何,攻击者似乎没有那么有利。

我发现了一种使用JWT而没有这种缺点的体系结构。反向代理位于外部不受信任的客户端和内部微服务的后端集合之间,这里由NordicAPI描述。客户端从授权服务器获取不透明令牌,并使用该令牌与服务器应用程序进行所有请求的通信。对于每个请求,代理将不透明令牌转换为JWT并缓存它们的关联。外部世界从不提供JWT,限制了窃取密钥造成的损害(因为代理会去身份验证服务器确认不透明的令牌)。然而,这种方法需要对每个客户端令牌进行解引用,就像会话ID需要对每个请求进行解引用一样,从而消除了JWT对客户端请求的好处。在这种情况下,JWT只允许服务在它们之间传递用户数据,而不必完全信任彼此——但我仍在努力理解这种方法的价值。

我的担忧似乎只适用于不受信任的客户端将JWT用作身份验证令牌的情况。然而JWT被许多知名的API所使用,包括Google API。我错过了什么?也许服务器漏洞很少是只读的?是否有降低风险的方法?

我相信您的想法是错误的。不要误解我的意思,你考虑安全性是很好的,然而,在服务器端进行双重检查、添加额外的检查以挫败无状态会话的目标等方面,你的做法似乎是沿着一条通往你自己理智终结的单行道走的。

总结两种标准方法:

  • JWT是无会话状态对象,由服务器端持有的密钥进行MAC。

  • 传统的会话标识符要么存储在内存中,要么存储在服务器端数据库中,正如您所说,它们经常被散列,以防止这些数据泄露时会话被劫持。

您也说得对,攻击者通常更难实现写访问。原因是数据库数据通常是通过SQL注入漏洞从目标系统中提取的。这几乎总是提供对数据的读取访问,但使用这种技术插入数据更困难,尽管并非不可能(一些漏洞实际上会导致对目标机器的完全根访问)。

如果你有一个漏洞,允许在使用JWT时访问密钥,或者允许在使用会话标识符时写入数据库表,那么游戏就结束了——你会受到威胁,因为你的用户会话可能会被劫持。

因此,不必更多破坏,这完全取决于漏洞的深度。

仔细检查JWT钥匙的安全性是否符合您的风险偏好:

  • 它们存放在哪里
  • 谁可以访问
  • 备份存储在哪里
  • 在应用程序的预生产和生产部署中是否使用了不同的密钥

缓解的方法与任何网络应用程序的良好实践一样:

  • 定期进行安全评估和渗透测试
  • 安全代码审查
  • 入侵检测和预防(IDS/IPS)
  • WAF

这些将帮助您评估真正的风险所在。过于专注于应用程序的某个特定方面是毫无意义的,因为这会导致忽略其他方面,这很可能会给您的商业模式带来更高的风险。JWT并不危险,也不一定比系统的其他组件有更大的风险,但如果你选择使用它们,你应该确保使用得当。你是否是,取决于你申请的特定背景,这很难从一般意义上进行评估,所以我希望我的答案能引导你朝着正确的方向前进。

当攻击者能够在基于JWT的系统中获得签名密钥时,这意味着他能够访问服务器后端本身。在这种情况下,所有的希望都破灭了。相比之下,当相同的攻击在基于会话的系统中成功时,攻击者将能够拦截到后端的用户名/密码身份验证请求,和/或自己生成会话id,和/或者更改验证会话id所需的验证例程和/或修改会话id指向的数据。用于缓解这种情况的任何安全机制对会话系统和JWT系统都有效。

最新更新