OpenID Connect 服务器流中的“state”参数可以防止啥攻击?
Posted
技术标签:
【中文标题】OpenID Connect 服务器流中的“state”参数可以防止啥攻击?【英文标题】:What attack does the "state" parameter in OpenID Connect server flow prevent?OpenID Connect 服务器流中的“state”参数可以防止什么攻击? 【发布时间】:2016-05-11 23:39:12 【问题描述】:不确定哪种 CSRF 攻击可以阻止 OpenID Connect 服务器流中的“状态”参数。谁能给我一个例子?
【问题讨论】:
【参考方案1】:它可以防止攻击者产生虚假身份验证响应的攻击,例如作为基本客户端配置文件的一部分,通过向客户端的重定向 URI 发送 code
。例如:在对用户进行网络钓鱼之后,攻击者可以注入被盗的code
,该code
将以这种方式与当前用户关联。 state
将请求和响应关联起来,因此如果不知道请求中使用的 state
参数,就不可能做出未经请求的精心制作的响应。
【讨论】:
汉斯,如果我理解正确,唯一的风险是“爱丽丝”将被登录到攻击者的帐户。这是正确的吗? 这是一个典型的 OAuth-for-login 风险,是的,但是还有更高级的攻击可以让攻击者以 Alice 的身份登录;假设通过不同的攻击从 Alice 那里窃取了code
,但没有 CSRF 保护,可以轻松利用 code
【参考方案2】:
通过比较授权请求和响应上的state
值,可以验证授权响应是否与请求相关。
到目前为止一切顺利;但是是什么阻止了对手使用从良性用户那里窃取的授权码来伪造授权响应呢? OpenID 客户端无法验证授权码是否与state
值相关。恕我直言,最好在授权请求中使用nonce
字段,因为一旦交换了授权代码,它就会在签名的id_token
中回显。现在,OpenID 客户端可以明确地将id_token
(授权证明)与授权请求相关联。
这样,我们可以减轻 CSRF 和重放攻击。还是我在这里忽略了什么?
老实说,我有点困惑为什么 OpenID Connect specs“建议”使用 state
,但留下 nonce
是可选的。
【讨论】:
【参考方案3】:该建议来自 OAuth2,并且遵循它会阻止支持“IdP 发起”流的能力。
OIDC 完全是关于 SSO 进入 RP(依赖方;又名“客户端”)系统,因为它们在 IdP(身份提供者;又名“提供者”)系统中进行了身份验证——并且有一些后端信任设置两个系统之间。
所以你有一个“身份验证请求”。这是从 RP 到 IdP 的重定向;它在 URL 的查询字符串中有“scope=openid”。然后你有一个“身份验证响应”;它在 URL 的查询字符串中有“code=XXXXX”。在这两个这些 GET 请求中,浏览器/最终用户在 RP 眼中是匿名。只有在 RP 验证“代码”(在后端)之后,RP 才会将身份(身份验证)分配给浏览器。
这意味着状态可以用来尝试阻止 CSRF 的唯一方法是,如果 RP 的应用程序将该状态值存储在浏览器中以唯一标识它。然后,当浏览器带着代码和状态到达 RP 时,它可以确保浏览器之前尝试过身份验证请求。但是 RP 永远不能保证代码来自特定的请求;状态可能会在该浏览器的上下文中重放。
这也意味着,RP 可以通过检查 HTTP“Referrer”标头是否表明“身份验证响应”来自预期的 IdP 来缓解 CSRF 攻击,而不是使用 State。
以这种方式使用 State 有什么好处?
您减轻的唯一实际攻击向量是让 A 使用 B 的代码而不是他们自己的代码登录 SiteX 的可能性。换句话说,爱丽丝理论上可以让鲍勃跟随一个链接并以她自己的身份登录鲍勃。
据我所知,此时,您要么让 OIDC 交换在 iFrame 中运行——并且攻击者找到了利用它的方法——要么您的浏览器的同源策略(也许 CORS 放宽了太多?)。在任何一种情况下,与攻击者在这种情况下可以做的其他事情相比,这种攻击向量似乎都非常小。哦,如果您有“关注链接并删除数据”的情况,那与 CSRF 无关。这完全是一个网站如何实现处理“深度链接”的问题(即保留未经身份验证的请求的状态,以便在成功身份验证后重放它——为最终用户提供便利)。
以这种方式使用 State 会失去什么?
您不能支持 IdP 发起的 SSO。当浏览器/最终用户已经在 IdP 并希望 SSO 进入 RP 时,IdP 将无法在单个重定向中执行此操作。解决方案/变通方法必须涉及浏览器点击 RP,然后返回 IdP,最后再次返回 RP。
【讨论】:
以上是关于OpenID Connect 服务器流中的“state”参数可以防止啥攻击?的主要内容,如果未能解决你的问题,请参考以下文章
OAuth 2.0 和 OpenID Connect 中的 JWT 安全性
移动应用程序 + REST 后端中的 OpenID Connect 身份验证流程(使用 KeyCloak)
验证 Google OpenID Connect JWT ID 令牌
验证 Google OpenID Connect JWT ID 令牌