状态参数在基于 OAuth2 的身份验证中可以防止什么样的 CSRF 攻击?

fyr*_*kov 7 security authentication csrf google-oauth openid-connect

我正在使用 Google OAuth2 API 进行身份验证部分。
我使用的是“服务器”流程,而不是“隐式”流程。

在执行获取code指南的步骤 1 时,建议使用该state参数以确保最终服务提供商将收到与其发起的身份验证请求相关的响应。

请参阅https://developers.google.com/identity/protocols/OpenIDConnect#createxsrftoken

据我所知,有可能code被盗,并redirect_uri猜测。

但我不明白为什么这被称为反CSRF保护?

根据wiki CSRF 攻击“利用网站对用户浏览器的信任”。
据我所知,应该在浏览器中保留一些敏感的东西,以使 CSRF 攻击成为可能。最经典的例子 - 身份验证 cookie。

但是与 OpenID-connect 代码流相关的浏览器中保存了什么?
它只是从服务提供者到身份提供者并返回的两个结果重定向。
代码本身作为 URL 参数在回调中传递。
浏览器的角色是被动的——被重定向两次。这里没有存储任何东西。

所以我的问题是究竟什么样的 CSRF 攻击可以state防止?谁能给个详细的例子?或者只是在谷歌指南中误用了术语“CSRF”?

Mvd*_*vdD 12

在 OAuth2 中使用授权代码流时,用户浏览到客户端应用程序,然后客户端应用程序将浏览器重定向到授权服务器以进行登录并获取访问令牌。

302 https://auth.server/authorize?response_type=code&client_id=....

Run Code Online (Sandbox Code Playgroud)

当您登录授权服务器后,它会将您重定向回带有颁发的代码的已注册重定向 URI。然后,客户端应用程序将用代码交换访问令牌,并可选择转到状态参数中编码的 URL。

现在,攻击者可能会诱骗您单击链接(来自电子邮件或其他内容),例如:

<a href="https://auth.server/authorize?response_type=code&client_id=...."
Run Code Online (Sandbox Code Playgroud)

This would execute the same request to the authorization server. Once you logged in and the authorization server redirects you back to the client application, the client application has no way of knowing whether the incoming GET request with the authorization code was caused by a 302 redirect it initiated or by you clicking that hyperlink in the malicious email.

The client application can prevent this by sticking some entropy in the state parameter of the authorization request. Since the state parameter will be included as a query parameter on the final redirect back to the client application, the client application can check if the entropy matches what it kept locally (or in a secure HTTP only cookie) and know for sure that it initiated the authorization request, since there's no way an attacker can craft a URL with entropy in the state parameter that will match something the client application keeps.

  • 解释得很好,很好的例子,谢谢!但我仍然缺少最后一部分 - 攻击者究竟可以在格式错误的链接中放入什么内容以使用户做出有害的事情?我只是看不到有任何空间。`redirect_uri` 是硬编码且精确的,任何尝试使用它都会导致“重定向 uri 不匹配”。此外,最后一个重定向是 GET,而不是状态更改。另一方面,如果攻击者在“state”中对可选 uri 进行了错误处理,那么对我来说这是一个悖论——“state”参数提供了一个攻击面,同时又阻止了攻击 (4认同)
  • 当然,如果您的站点遵循 REST 原则,则它不应通过 GET 请求更改状态。然而,并非所有网站都遵循这些准则。此外,如果站点支持从状态参数重定向到 URL,则可能容易受到开放重定向攻击,从而使攻击者可以选择从攻击者控制的域加载任何页面。 (4认同)
  • CSRF URL 中使用的内容源自攻击者自己的 OAuth 会话。攻击者独立执行(部分)OAuth 工作流程并拦截 HTTP 流量。工作流程在重定向回客户端站点后立即暂停。这就是 @MvdD 所说的“客户端应用程序无法知道带有授权代码的传入 GET 请求是否是由 302 重定向引起的...” - 攻击者在此插入自己的 GET 请求。最终结果是 - 用户的帐户现在已绑定到其他服务上的攻击者帐户 (4认同)