开发者工具 · JWT 解码器
alg:none 攻击和密钥混淆:为什么验证者必须固定算法
· 为什么它很重要
jwt 安全 密码学
如果验证者让令牌选择自己的算法,攻击者可以不选择任何算法或将 RSA 替换为 HMAC。这篇文章解释了这两种攻击以及防止它们的规则。
验证自身的令牌 - 标头字段如何成为攻击面
算法标签位于攻击者控制的令牌输入中。如果验证者将该标签视为选择任何可用验证模式的权限,则令牌开始影响用于判断自身的规则。 ToolAcre 精确地公开标签,以便审阅者可以看到它,但从不以加密方式对其进行操作。
安全方向是相反的:可信服务配置定义可接受的算法系列和关联密钥,然后传入标头必须匹配该策略。解码面板无法提供该策略,并且不能仅仅因为它突出显示可疑值而被误认为是保护。
存储库标记 alg:none 但未建立不安全 JWT 背后的规范历史记录
该实现将 `alg: none` 视为未签名的声明,并警告接受它将接受任意内容。它还单独报告一个空的第三段。存储库证据支持在经过身份验证的工作流程中拒绝此类输入;它没有记录为什么不安全的 JWT 最初包含在规范中。
因此,历史措辞是更正的而不是发明的。操作上重要的事情很清楚:需要签名凭据的服务不得允许令牌标头禁用签名检查。 ToolAcre 本身不执行任何验证,因此它显示 `none` 的能力只是为了检查而进行的检测。
alg:none 攻击 — 剥离签名并要求验证者接受空签名
未签名攻击会更改标头以请求 `none`,根据需要更改声明,并且不提供签名字节。每个段在语法上仍然有效,前两个段解码为经过修饰的 JSON。宽容的验证者会将攻击者的偏好转换为身份验证绕过。
严格验证者没有在需要签名令牌时将此输入升级到受信任状态的分支。 ToolAcre 的警告有助于在调试期间识别形状,但读取单词 `none` 并不能阻止后端做出错误的决定。强制执行属于凭证被消耗的地方。
密钥混淆 — 将公钥作为 HMAC 秘密提供,以便将 RS256 令牌验证为 HS256
当验证者允许具有不兼容密钥角色的算法系列并且无法将每个选择绑定到正确的密钥类型时,就会出现密钥混淆。公共 RSA 验证密钥不是 HMAC 秘密。在攻击者更改算法标签后将其字节视为 1 会破坏预期的 public/private 分隔。
防止此类错误需要的不仅仅是检查签名形状的段。该服务必须通过可信配置来配对预期的算法、密钥类型、发行者和令牌配置文件。显示 RS256 或 HS256 的解码器无法判断后端是否维护这些绑定。
修复 - 将接受的算法固定在验证器中,并且永远不要从令牌中派生它们
在验证者配置中固定接受的算法,并在发行人合同允许的范围内保持列表的范围尽可能窄。拒绝签名凭证流的 `none` 并拒绝不匹配,而不是尝试其他算法。不要从未经验证的标头或有效负载声明中派生允许列表。
键查找遵循相同的原则。 `kid` 可以在已信任的候选者中进行选择,但不得创建新的信任源。不应仅仅因为令牌请求标头 URL 或嵌入密钥而遵循它们。验证者独立决定其来源。
工作示例 - 读取 ToolAcre JWT 解码器中的标头以发现 alg:none,以及为什么发现它与受保护不同
创建一个无害的令牌标头,声明 `none` 并将第三段留空。 ToolAcre 解码 JSON,报告声明的算法,警告它未签名并记录缺失的签名。这正是检查工具所期望的行为。
该练习并不能证明 API 拒绝令牌。通过针对实际验证器和配置的受控负面测试单独确认这一点。如果 API 接受它,则修复属于该验证边界;向解码器添加更大声的警告不会保护请求。
这不包括 - 许多特定于库的修复;请参阅 RFC 8725 和您的库的变更日志
库 API、默认值和历史修复因产品和版本而异。该模块没有确定哪个选项名称将算法固定在堆栈中,本文有意不发明任何内容。阅读所选库的当前文档和变更日志,然后在您自己的测试套件中练习拒绝案例。
还测试错误的密钥类型、未知的 `kid` 值、缺少签名和意外的令牌配置文件。目标是表明配置胜过令牌建议。成功的解码不属于这些接受断言,因为语法成功与每个恶意示例兼容。
要点:由验证者决定,而不是令牌 — 解码器可以帮助您查看标头,但只有固定验证才能保护您
验证者决定;令牌没有。 ToolAcre 可能会显示标有 `none` 的标头、不熟悉的算法或令人惊讶的密钥标识符。这种可见性有助于分类,但只有固定的算法策略和正确绑定的可信密钥才能阻止接受。
绝不建议启用 `none`、从不受信任的标头中选择验证密钥或将显示的签名长度视为验证。解码进行检查,然后通过受控测试证明真实加密边界上的拒绝和接受行为。