JSON Web Tokens (JWT) 已成为一种流行的方法,用于以 JSON 对象的形式在各方之间安全地传输信息。它们紧凑、独立且易于验证,是 Web 应用程序中身份验证和信息交换的理想选择。它们理论上可以包含任何类型的数据,但最常用于发送有关用户的信息(“声明”)作为身份验证、会话处理和访问控制机制的一部分。
JWT 由三部分组成,以点分隔:标头、有效负载和签名。它们遵循以下格式:
header.payload.signature
标头:包含有关令牌类型和用于保护令牌的加密算法的元数据。它通常如下所示:
{
"alg": "HS256",
"typ": "JWT"
}
有效负载:包含声明,即关于实体(通常是用户)和其他数据的声明。声明分为保留、公开或私有,它们可以包含用户 ID、角色和到期时间等信息。示例:
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
签名:使用指定算法(例如 HS256、RS256)和只有服务器知道的密钥对标头和有效负载进行编码来创建。它确保令牌的完整性并验证它未被篡改。
JWT 攻击的影响
JWT 攻击的影响通常很严重。如果攻击者能够创建具有任意值的有效令牌,他们就可能提升自己的权限或冒充其他用户,从而完全控制他们的帐户。
JWT 攻击的漏洞是如何产生的?
-
弱密钥管理:如果用于签署 JWT 的密钥较弱或未得到安全管理,则容易受到暴力攻击。弱密钥可以通过计算能力猜测或破解。
-
算法漏洞:选择弱的加密算法或错误配置算法可能会危及 JWT 的安全性。
-
验证不足:服务器端无法正确验证 JWT 可能导致各种漏洞。缺乏输入验证可能导致注入攻击,即恶意负载被插入 JWT。
-
敏感信息的泄露:如果在 JWT 有效负载中包含敏感信息而没有适当的加密或保护,则可能会使其遭受未经授权的访问或篡改。
-
缺乏令牌过期和撤销机制:不为 JWT 实施过期或撤销机制会导致它们无限期地保持有效,从而增加了攻击者滥用它们的机会。
-
未能执行访问控制:基于 JWT 声明的访问控制执行不充分可能导致权限提升或对敏感资源的未经授权的访问。
-
第三方漏洞:如果 JWT 实现依赖于第三方库或服务,并且这些库存在安全漏洞或者没有保持最新,则可能会引入漏洞。
有多种类型的攻击可以针对 JSON Web 令牌 (JWT),利用其实现、传输或验证中的漏洞。以下是一些常见的 JWT 攻击类型:
接受任意签名
JWT 库通常提供一种验证令牌的方法和另一种仅解码令牌的方法。例如,Node.js 库 jsonwebtoken 具有 verify() 和 decrypt()。
有时,开发人员会混淆这两种方法,只将传入的令牌传递给decode()方法。这实际上意味着应用程序根本不验证签名。
使用jwt_tool通过未验证的签名绕过 JWT 身份验证https://github.com/ticarpi/jwt_tool
减轻
jsonwebtoken 库通常用于 Node.js 环境中处理 JWT。要使用 jsonwebtoken 库验证 JWT,可以使用 verify 方法。下面是一个示例代码片段,演示了如何在 Node.js 中使用 jsonwebtoken 验证 JWT:
在此代码片段中:
-
jwt.verify 方法用于验证 JWT 签名。它需要三个参数:要验证的 JWT 令牌、用于对令牌进行签名的密钥,以及使用解码后的令牌或验证失败时会调用的回调函数。
-
将 jwtToken 变量替换为您的实际 JWT 令牌,将 secretKey 变量替换为您的实际密钥。
-
如果 JWT 签名有效,则将使用解码后的令牌调用回调函数,该令牌包含来自 JWT 有效负载的声明。否则,将使用描述验证失败的错误对象调用回调函数。
使用 jsonwebtoken 库的验证方法可确保使用提供的密钥正确验证 JWT 签名,有助于防止接受具有任意签名的 JWT。
接受无签名的令牌
除其他事项外,JWT 标头还包含一个 alg 参数。这会告诉服务器使用哪种算法对令牌进行签名,以及在验证签名时需要使用哪种算法。
JWT 可以使用多种不同的算法进行签名,但也可以不签名。在这种情况下,alg 参数设置为 none,表示所谓的“不安全的 JWT”。
使用jwt_tool 执行带有sub:administrator声明的alg:none攻击
减轻
为了缓解 JSON Web Tokens (JWT) 中的“alg:none”攻击,您需要确保您的应用程序拒绝使用“none”算法的 JWT,并且仅接受使用安全签名算法的令牌。以下代码片段演示了如何使用 Node.js 中的 jsonwebtoken 库实现此缓解措施:
在此代码片段中:
-
jwt.verify方法用于验证 JWT 签名。但是,还提供了一个附加选项{ algorithm: [...] }来指定可接受算法的列表。在这种情况下,仅接受HMAC 算法( HS256、HS384、HS512 ),并明确排除none算法。
-
将jwtToken变量替换为您的实际 JWT 令牌,将secretKey变量替换为您的实际密钥。
-
如果 JWT 令牌使用“none”算法,则验证将失败,并且将使用描述验证失败的错误对象调用回调函数。您应该适当地处理此验证失败(例如,记录日志、拒绝令牌)。
-
如果 JWT 签名有效且使用可接受的算法之一,则将使用解码后的令牌调用回调函数,该令牌包含来自 JWT 有效负载的声明。然后,您可以继续在应用程序中使用解码后的令牌。
暴力破解密钥
某些签名算法(例如 HS256 (HMAC + SHA-256))使用任意独立字符串作为密钥。就像密码一样,这个密钥不能被攻击者轻易猜出或暴力破解,这一点至关重要。否则,他们可能能够使用他们喜欢的任何标头和有效负载值创建 JWT,然后使用该密钥通过有效签名重新签署令牌。
例子:
使用jwt_tool执行 JWT 密钥暴力破解
减轻
在此代码段中,crypto.randomBytes(32).toString('hex') 用于生成 256 位(32 字节)加密安全随机字符串,然后将其转换为十六进制格式。这可确保用于 JWT 签名的密钥强大且不可预测。
请记住安全地存储此密钥,并避免将其硬编码在代码库中或公开暴露。
通过 jwk 参数注入自签名 JWT
JSON Web 签名 (JWS) 规范描述了一个可选的 jwk 标头参数,服务器可以使用该参数将其公钥以 JWK 格式直接嵌入令牌本身中。理想情况下,服务器应仅使用有限的公钥白名单来验证 JWT 签名。但是,配置错误的服务器有时会使用嵌入在 jwk 参数中的任何密钥。
使用jwt_tool进行 jwk 标头注入,绕过 JWT 身份验证
如何防止 JWT 攻击
防止 JWT 攻击需要结合安全实施实践、遵守加密标准和强大的验证机制。以下是一些有助于缓解 JWT 漏洞的策略:
-
使用强加密和签名算法:选择强加密算法来签名和加密 JWT,例如使用 SHA-256 的 HMAC 或密钥长度至少为 2048 位的 RSA。避免使用弱算法或弃用的算法,例如 MD5 或 SHA-1。
-
确保密钥安全:保护用于 JWT 签名和加密的密钥。安全存储密钥,仅允许授权人员访问,并避免在源代码或配置文件中对密钥进行硬编码。
-
验证 JWT 签名:始终验证传入 JWT 的签名以确保其完整性和真实性。在信任令牌内容之前,请使用适当的加密算法和密钥验证签名。
-
实现令牌过期:为 JWT 设置合理的过期时间,以限制其使用寿命并降低由于令牌被盗或滥用而导致未经授权的访问的风险。及时使过期的令牌失效,并在必要时要求客户端获取新令牌。
-
使用短期令牌:考虑使用具有有限有效期(例如几分钟或几小时)的短期 JWT,以最大限度地减少攻击者利用被盗令牌的机会窗口。
-
实施令牌撤销:在发生入侵或注销事件时实施令牌撤销或失效机制。维护已撤销令牌的黑名单或撤销列表,以防止其被重复使用。
-
包含受众(aud)声明:使用“aud”声明指定 JWT 的目标受众(例如 API 或服务)。在令牌验证期间验证受众声明是否与预期值匹配,以防止令牌滥用。
-
验证令牌声明:验证 JWT 有效负载中的所有相关声明,例如颁发者 (iss)、主题 (sub) 和任何自定义声明,以确保它们符合预期标准。拒绝具有无效或意外声明的令牌,以防止令牌被操纵。
-
保护令牌传输:通过 HTTPS 安全地传输 JWT,以防止窃听和中间人攻击。避免通过未加密的通道发送令牌,或将其包含在外部方可见的 URL、查询参数或 HTTP 标头中。
-
实施访问控制:根据 JWT 声明实施细粒度的访问控制,以限制用户对应用程序内资源和功能的访问。根据需要实施基于角色的访问控制 (RBAC) 或基于属性的访问控制 (ABAC) 机制。
-
实施速率限制:对令牌发行和身份验证端点实施速率限制,以防止暴力攻击和令牌滥用。
-
定期安全审计和更新:定期对 JWT 实施进行安全审计,包括代码审查、渗透测试和漏洞评估。随时了解 JWT 库和依赖项的安全更新和补丁。
通过实施这些预防措施,开发人员可以增强基于 JWT 的身份验证系统的安全性,并降低与 JWT 相关的攻击的风险。
进一步学习
-
https://www.youtube.com/watch?v=zWVRHK3ykfo
-
https://portswigger.net/web-security/jwt
-
https://dazzyddos.github.io/posts/JWT_MindMap/
原文始发于微信公众号(Ots安全):解码 JWT 漏洞:深入探讨 JWT 安全风险及缓解措施
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论