在基于 OAuth2 的身份验证中,状态参数可以防止哪种 CSRF 攻击?

What kind of CSRF attack does state parameter prevent in OAuth2-based authentication?

我正在使用 Google OAuth2 API.
处理身份验证部分 我使用的是 "server" 流,而不是 "implicit"。

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

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

了解到code有可能被盗,redirect_uri猜到了

但是我不明白为什么叫反CSRF保护?

根据 wiki CSRF 攻击 "exploits the trust that a site has in a user's browser"。
据我所知,一些敏感的东西应该保留在浏览器中,以使 CSRF 攻击成为可能。最经典的例子——认证cookie。

但是与 OpenID 连接代码流相关的浏览器中保留了什么?
这只是从服务提供者到身份提供者并返回的两个后续重定向。
代码本身作为 URL 参数传递给回调。
浏览器的角色是被动的 - 被重定向两次。这里没有存储任何内容。

所以我的问题是 state 到底防止了哪种 CSRF 攻击?谁能举个详细的例子?还是只是误用了 google 指南中的术语 "CSRF"?

CSRF的objective是通过点击link 由攻击者发送。这种 activity 的一个例子是删除用户自己在网站上的帐户。假设用户登录到网站,来自用户浏览器的请求被网站服务器信任,网站服务器无法发现(没有 CSRF 令牌)用户实际上是被欺骗发出该请求。

在Google OAuth2(授权码授予类型)的情况下,注意对Google授权服务器的初始请求包含用户实际想要访问的url认证成功。攻击者可以出于某种恶意小心地构建 url 并让用户使用它。

状态令牌检查使服务器能够确保请求确实来自其自己的网站,而不是来自任何其他地方。如果攻击者使用一些随机状态令牌创建 url,服务器将无法识别并拒绝请求。

如果您有这样的疑问,您必须参考的最佳资源是规范。对于 OAuth 2.0,这是 RFC6749 . There is a dedicated section in the specification which discuss about Cross-Site Request Forgery

Cross-site request forgery (CSRF) is an exploit in which an attacker causes the user-agent of a victim end-user to follow a malicious URI (e.g., provided to the user-agent as a misleading link, image, or redirection) to a trusting server (usually established via the presence of a valid session cookie).

从规范的角度来看,您必须在您的应用程序中实现 状态 处理机制

The client MUST implement CSRF protection for its redirection URI. This is typically accomplished by requiring any request sent to the redirection URI endpoint to include a value that binds the request to the user-agent's authenticated state (e.g., a hash of the session cookie used to authenticate the user-agent). The client SHOULD utilize the "state" request parameter to deliver this value to the authorization server when making an authorization request.

还有详细的解释,直接来自specifaciton

A CSRF attack against the client's redirection URI allows an attacker to inject its own authorization code or access token, which can result in the client using an access token associated with the attacker's protected resources rather than the victim's

注入攻击者的授权代码,然后操纵您的应用程序以攻击者想要的方式运行。

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

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

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

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

<a href="https://auth.server/authorize?response_type=code&client_id=...."

这将对授权服务器执行相同的请求。一旦您登录并且授权服务器将您重定向回客户端应用程序,客户端应用程序就无法知道传入的带有授权代码的 GET 请求是由它发起的 302 重定向引起的,还是由您单击它引起的hyperlink 在恶意邮件中。

客户端应用程序可以通过在授权请求的状态参数中添加一些熵来防止这种情况。由于状态参数将作为查询参数包含在最终重定向回客户端应用程序时,客户端应用程序可以检查熵是否与它保存在本地(或在安全的 HTTP 专用 cookie 中)匹配,并确定它启动了授权请求,因为攻击者无法在状态参数中制作一个 URL 熵来匹配客户端应用程序保留的内容。