根据我对 PKCE 的了解,恶意浏览器扩展有可能从浏览器历史记录中窃取授权代码,但不能窃取代码验证程序。如果这是真的,那么为什么还要对代码验证器进行哈希处理来进行代码挑战呢?
您对代码验证器进行哈希处理,使攻击者更难窃取它。如果他们设法以某种方式拦截授权请求中发送的代码质询,但这仍然不够,因为您需要原始代码验证程序将授权代码交换为访问令牌。这只是提高 PKCE 安全级别的另一项措施。
顺便说一句,对代码验证器进行散列并不是必须的。规范中的“散列方法”之一是“普通”,这意味着您不对验证器进行散列。尽管建议对其进行哈希处理,但如果没有障碍的话。
坚定的黑客可以使用查找表轻松找到输入。
我认为事实并非如此。
code_verifier
由 A-Z / a-z / 0-9 / - / . / _ / ~
(66 个字符)中的 43-128 个字符组成。所以有66^43 - 66^128
的可能性。
从角度来看,至少有这么多组合:
1,739,358,998,350,143,493,317,779,844,390,084,859,341,773,852,978,927,698,440,263,217,183,107,995,140,096
至少超过“25亿”。
我认为你可以为传统密码构建一个彩虹表,但是
code_verifier
并不是由人类创建的意义上的密码。这是一种高熵加密随机刺痛,意味着没有一种可能性比另一种可能性更大,我们也无法猜测它会是什么。
我们已经预计创建查找表的计算速度会很慢,但我认为存储也是不可行的。
但即便如此,还有更多需要考虑的事情。 由于授权代码是短暂且一次性的,这意味着攻击者在每个 OAuth 流程中都有一次机会获得正确的授权。
授权码必须是短期且一次性使用的。如果 授权服务器观察到多次尝试交换 访问令牌的授权码,授权服务器 应尝试撤销所有已授予的访问令牌 被泄露的授权码。
请注意,PKCE 实际上要求使用 SHA-256 (如果客户端中存在此功能)。
来自 RFC-7636“OAuth 公共客户端代码交换的证明密钥”
如果客户端能够使用“S256”,则必须使用“S256”,因为 “S256”是服务器上强制实施(MTI)的。客户是 仅当它们不能支持“S256”时才允许使用“plain” 技术原因并通过带外配置知道 服务器支持“普通”。
简单的转换是为了与现有的兼容 部署以及无法使用 S256 的受限环境 转变。
老实说,似乎如果攻击者可以拦截
code_challenge
,那么他应该在尝试绕过 PKCE 时尝试按原样使用它。