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.
The Attack
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?
Prevention
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.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…