是什么阻止了OpenID Connect服务器流中的“状态”参数?

las*_*ayf 3 security authentication csrf openid-connect oauth2

不确定哪种CSRF攻击会阻止OpenID Connect服务器流中的“状态”参数。有人可以给我一个例子吗?

Han*_* Z. 7

它通过向code客户端的重定向URI 发送来防止攻击者产生虚假的身份验证响应(例如,作为基本客户端配置文件的一部分)的攻击。例如:仿冒用户后,攻击者可以code以这种方式注入将与当前用户关联的被盗内容。将state请求和响应相关联,因此在不知道state请求中使用的参数的情况下,无法进行未经请求的精心设计的响应。


Emi*_*mil 7

通过比较state授权请求和响应上的值,该想法是能够验证授权响应与请求相关。

到目前为止,一切都很好; 但是,什么阻止了使用良性用户窃取的授权码来阻止对手伪造授权响应的问题呢?OpenID客户端无法验证授权码是否与state值相关联。恕我直言,最好使用nonce授权请求中的字段,因为id_token一旦交换了授权代码,该字段就会在签名内回显。现在,OpenID客户端可以明确地将id_token(授权证明)与授权请求相关联。

这样,我们既减轻了CSRF又减轻了重放攻击。还是我忽略了这里的东西?

老实说,我有点困惑为什么OpenID Connect 规范 “建议”使用,state但是却是nonce可选的。


Gra*_*ger 6

该建议来自 OAuth2,遵循它会阻止支持“IdP 发起”流程的能力。

OIDC 的全部内容是通过 SSO 进入 RP(依赖方;又名“客户端”)系统,因为它们在 IdP(身份提供商;又名“提供商”)系统中进行身份验证 — 并且两者之间存在一些后端信任设置系统。

所以你有一个“身份验证请求”。这是从 RP 到 IdP 的重定向;它在 URL 的查询字符串中包含“scope=openid”。然后你就有了一个“身份验证响应”;它在 URL 的查询字符串中包含“code=XXXXX”。在这两个GET 请求中,浏览器/最终用户在 RP 眼中都是匿名的。只有在 RP 验证“代码”(在后端)之后,RP 才会向浏览器分配身份(身份验证)。

这意味着State 可用于尝试阻止 CSRF 的唯一方法是 RP 的应用程序将该 State 值存储在浏览器中以唯一标识它。然后,当浏览器带着代码和状态来到 RP 时,它可以确保浏览器之前曾尝试过身份验证请求。但 RP 永远不能保证该代码来自特定请求;状态可能会在该浏览器的上下文中重播。

这还意味着,RP 可以通过检查 HTTP“Referrer”标头是否指示“身份验证响应”来自预期的 IdP 来减轻 CSRF 攻击,而不是使用状态。

以这种方式使用 State 你能得到什么?

您减轻的唯一实际攻击媒介是使 A 人使用 B 人的代码(而不是他们自己的代码)登录 SiteX 的可能性。换句话说,理论上,爱丽丝可以让鲍勃点击链接并以她自己的身份登录鲍勃。

据我所知,此时,您要么已经在 iFrame 中运行了 OIDC 交换,并且攻击者已经找到了利用该交换的方法,要么您的浏览器的 Same-有问题起源政策(也许 CORS 放松得太过分了?)。无论哪种情况,与攻击者在这种情况下可以做的其他事情相比,这种攻击向量似乎都很小。哦,如果你遇到“点击链接并删除数据”的情况,那与 CSRF 无关。这完全是一个如何实现站点来处理“深层链接”的问题(即保留未经身份验证的请求的状态,以便在成功身份验证后重播它,以方便最终用户)。

以这种方式使用 State 你会损失什么?

您无法支持 IdP 发起的 SSO。当浏览器/最终用户已经位于 IdP 并希望 SSO 进入 RP 时,IdP 将无法通过单个重定向来完成此操作。解决方案/变通方法必须涉及浏览器命中 RP,然后返回 IdP,最后再次返回 RP。