I am using PHP library for OAuth2.0 v20
In draft20, there is a mention of the use of state to prevent CSRF
So far, my own web app that implements this PHP library allows the following:
Do I need to use state for all of the 3 situations above?
If so, what is a good example of "state"?
what makes a good "state"?
Any ideal length? Any minimum length? Any maximum length?
Any ideal makeup? alphanumeric including upper case?
The primary reason for using the state parameter is to mitigate CSRF attacks by using a unique and non-guessable value associated with each authentication request about to be initiated. That value allows you to prevent the attack by confirming that the value coming from the response matches the one you sent.
For most cases, we recommend using the Authorization Code Flow with PKCE because the Access Token is not exposed on the client side, and this flow can return Refresh Tokens. To learn more about how this flow works and how to implement it, see Authorization Code Flow with Proof Key for Code Exchange (PKCE).
It might be helpful to step through an example CSRF exploit in order to understand how a state parameter mitigates such an attack. In this example Mallory is the attacker and Alice is the victim.
Mallory visits some client's website and starts the process of authorizing that client to access some service provider using OAuth
The client asks the service provider for permission to request access on Mallory's behalf, which is granted
Mallory is redirected to the service provider's website, where she would normally enter her username/password in order to authorize access
Instead, Mallory traps/prevents this request and saves its URL
Now, Mallory somehow gets Alice to visit that URL. If Alice is logged-in to the service provider with her own account, then her credentials will be used to issue an authorization code
The authorization code is exchanged for an access token
Now Mallory's account on the client is authorized to access Alice's account on the service provider
So, how do we prevent this using the state
parameter?
The client should create a value that is somehow based on the original user's account (a hash of the user's session key, for example). It doesn't matter what it is as long as it's unique and generated using some private, unguessable information about the original user.
This value is passed to the service provider in the redirect from step three above
Now, when Mallory gets Alice to visit the saved URL (step five above), that URL includes the state
parameter generated with Mallory's session information
The authorization code is issued and sent back to the client in Alice's session along with Mallory's state
parameter
The client generates a new state
value based on Alice's session information and compares it to the state
value that was sent back from the authorization request to the service provider. This value does not match the state
parameter on the request, because that state
value was generated based on Mallory's session information, so it is rejected.
An attacker should not be able to generate a state value for any specific user and, therefore, tricking a user into visiting their authorization URL has no effect.
Just for #1 -- 3-legged authorization using Authorization Code flow.
When your application exchanges the authorization code for an access token, you want to be sure that the OAuth flow which resulted in the authorization code provided was actually initiated by the legitimate user. So, before the client application kicks off the OAuth flow by redirecting the user to the provider, the client application creates a random state value and typically store it in a server-side session. Then, as the user completes the OAuth flow, you check to make sure state value matches the value stored in the user's server-side session-- as that indicates the user had initiated the OAuth flow.
A state value should typically be a pseudo-random unguessable value. A simple value can be generated as an int with the rand() function in PHP, though you could get more complex as well to provide greater assurance.
The state exists to prevent things like me sending you a link via e-mail which contains an authorization code for my account, you clicking on it and the application pushing all the data into my account unbeknownst to you.
Some additional information is in the OAuth 2.0 threat model document: https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-threatmodel-00
In particular, see the section on CSRF protection: https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-26#section-10.12
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With