I'm trying to understand why the "state" value is recommended in OAuth2 flows.
Imagine a Google OAuth2 flow:
- Backend returns the authorize url with the desired scopes
- Frontend redirects the User to the returned url
- User authorizes the App and is redirected back to the callback_url
- Frontend at callback_url sends the authorization_code to the Backend
- Backend exchanges the authorization_code for an access_token
Let's say, in the first step, instead of the Backend, an attacker tricked a User into using their version of "authorize" url. (with modified scopes and properties)
The user will, again, get redirected to a trusted callback_url and the attacker has no way of obtaining the access_token.
Seems like as long as the callback_url is safe AND the Backend does not leak the client_secret, the attacker has no way to hijack the access_token.
So the "state" does not really have any benefits in this scenario.
However, I can imagine in some OAuth2 flows, the attacker can modify the authorize url (to change the "scopes" of the authorize url for example) and using a "state" can detect these flows and prevent an access_token being issued. which can be life-saving.
Is my understanding of this situation correct or are there cases where the state is necessary?