【问题标题】:Are breaches of JWT-based servers more damaging?破坏基于 JWT 的服务器是否更具破坏性?
【发布时间】:2016-09-26 11:52:34
【问题描述】:

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


我已经看到很多关于 JSON Web 令牌安全性的讨论——重放、撤销、数据透明度、令牌指定的算法、令牌加密、XSS、CSRF——但我没有看到任何关于由依赖于签名密钥。

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

将此与基于会话 ID 的服务器入侵进行对比。如果此服务器正在对密码进行哈希处理,则攻击者必须在会话 ID 过期之前为每个用户单独获取和使用会话 ID。如果服务器只存储会话 ID 的哈希值,攻击者将不得不写入服务器以确保访问。无论如何,攻击者的优势似乎较小。

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

我的担忧似乎只适用于不受信任的客户端使用 JWT 作为身份验证令牌。然而,包括 Google API 在内的许多知名 API 都在使用 JWT。我错过了什么?也许服务器违规很少是只读的?有没有办法降低风险?

【问题讨论】:

  • 我想到了一个解决方案,要求攻击者在 RAM 中找到密钥,但显然以服务器必须在每个请求上验证两个签名为代价。集群的每个服务器在启动时都会生成一个公钥/私钥对。它将公钥与 keyID 一起存储在数据库中,但当服务器关闭时,私钥会消失。每个 JWT 都使用集群范围的机密(以防止 DoS 攻击攻击数据库)和 JWT 通过 keyID 标识的密钥进行签名。服务器缓存 keyID 和关联的公钥。不过,我不确定将曝光转移到 RAM 有多大帮助。
  • 服务器对每个请求的电子签名验证有什么问题?你应该这样做。它是一个 RSA-HMAC 签名,简单且验证速度非常快。如果密钥被盗,它会发出另一个。如果您担心密钥被盗,请使用硬件令牌 (HSM)
  • 取决于你所说的“验证”,我想。您的意思是服务器应该“为每个请求”验证令牌签名吗?如果这就是您的意思,但密钥已被无意中窃取,则签名将正确验证即使是伪造的令牌。这就是我要提出的观点。更有可能的是,我不明白你的意思。我的前提是没有人知道钥匙被偷了。这比没有人知道密码和会话 ID 哈希被盗要糟糕得多。
  • 好吧,如果密钥被无意中窃取了,那你的问题就很严重了。但我认为智威汤逊值得。 1) 缓解:定期更换密钥。 2) 避免:使用加密硬件 (HSM) 来存储密钥。它足够便宜 3)预防:审核您的网络基础设施 4)减少影响:它根据用户组或访问区域使用不同的密钥
  • 标记并要求模组迁移到security.stackexchange.com - 你可能会在那里得到答案。

标签: security digital-signature jwt secret-key


【解决方案1】:

我相信你的想法是错误的。不要误会我的意思,您正在考虑安全性很好,但是您在服务器端仔细检查事物、添加违反无状态会话目标的额外检查等方面的处理方式似乎是一致的一条通往自己理智尽头的单行道。

总结两种标准方法:

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

  • 传统的会话标识符要么存储在内存中,要么存储在服务器端的数据库中,正如您所说,通常会进行哈希处理,以防止在数据泄露时会话被劫持。

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

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

所以不一定更多破坏,这完全取决于漏洞的深度。

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

  • 它们存储在哪里?
  • 谁有权访问?
  • 备份存储在哪里?
  • 在您的应用的预生产和生产部署中是否使用了不同的密钥?

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

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

这些将帮助您评估您的真正风险所在。如此专注于应用程序的某个特定方面是没有意义的,因为这会导致忽略其他方面,这很可能会给您的业务模型带来更高的风险。 JWT 并不危险,并且不一定比系统的其他组件具有更大的风险,但是如果您选择使用它们,则应确保正确使用它们。无论您是否是应用程序的特定上下文,这在一般意义上很难评估,所以我希望我的回答能引导您朝着正确的方向前进。

【讨论】:

  • 感谢您的周到回复。很高兴听到一些确认,即写访问违规不像读访问违规那样常见。但是,我没有看到您如何解决我的问题。当传统的基于会话的服务器被破坏为只读时,攻击者的工作仍然很困难,因为他得到的只是散列凭据。当基于 JWT 的服务器被破坏为只读时,攻击者随后可以通过签名密钥获得免费、不受限制的访问。这些违规行为发生了,因此似乎值得考虑。
  • 我应该澄清的是,必须违反 JWT 颁发机构,而不是该机构的任何客户端恰好也是服务器。
  • 正如我试图暗示的那样,这是一个相当广泛的问题。保护密钥的安全将取决于权限的单独实施。你是这里的网站还是权威?密钥是存储在易受 SQLi 攻击的数据库中,还是存储在易受文件包含或目录遍历影响的文件系统中?如果您想总体上降低风险,您可以诉诸拆分密钥 - 一半的密钥在数据库中,另一半在文件系统中。那么攻击者需要两个漏洞来危害你。如果不查看您的系统,我真的无法更具体。
  • 是的,可以采取许多措施来帮助保护密钥。如果不使用物理设备,获得只读访问权限的攻击者将获得两个密钥。无论如何,听起来您同意我的观点,这是一个需要解决的问题。我最终将部署到无法使用加密硬件的云端。
  • 我可能错过了您上次评论中的某些内容。如果一半的密钥在一台服务器的文件系统中,而另一半在另一台服务器的数据库中,则必须破坏的服务器数量增加一倍。这确实降低了风险。谢谢你的建议!
【解决方案2】:

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

【讨论】:

  • 我认为您已经陈述了允许人们继续将密钥存储在方便的地方的假设。 OWASP 加密存储表 (owasp.org/index.php/Cryptographic_Storage_Cheat_Sheet) 不同意,赛门铁克的 2016 年互联网安全威胁报告,第 3 页也不同意。 72,(symantec.com/security-center/threat-report)。
  • 我无法找到关于有多少违规行为是只读与读/写的统计数据。从逻辑上讲,攻击者获得读取访问权限的情况多于读取和写入权限,这仅仅是因为帐户通常能够读取的内容多于写入的内容。此外,在不被发现的情况下读取数据很容易,而在不冒险破坏某些东西的情况下写入数据要困难得多。攻击者将在尝试修补他没有源的应用程序之前利用敏感数据。非常值得警惕读访问场景。
猜你喜欢
  • 2013-02-20
  • 1970-01-01
  • 1970-01-01
  • 2015-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多