1

We are trying to build a set of REST APIs which will be authenticated by using attached ID token generated by an OAuth provider.

I am trying to understand how to use the state token passed in with the redirect URL during an OAuth "authorization flow".

How would the state token prevent the attack in the following scenario:

Assumption: The back-end OAuth client(which will service the REST API requests) has a session map of user <-> state token.

Scenario:

  1. Malicious user tries to authenticate with our service.
  2. Our service generates the authentication URL to OAuth provider with the state token. The state token is attached to the malicious user on our server.
  3. The malicious user authenticates himself on the authentication URL and traps the redirect URL request before hitting our server.
  4. Now assume that he manages to force a valid user of our service to navigate to the trapped redirect URL.
  5. The OAuth client(our server) on receiving the redirect URL would validate the state token, this is because:
    • the OAuth code in URL would successfully exchanged by the OAuth provider with an ID token which matches the identity of the malicious user.
    • the OAuth client(our server) would compare the state token in the URL with the state token associated with identity carried by the ID token.
  6. Now a valid user would end up operating on the malicious user's account and potentially reveal sensitive information to the malicious user.

How do we protect against such attacks? Or are we missing something in the way we are implementing state token validation.

0

How do we protect against such attacks?

This is exactly the attack scenario, the state parameter is used to protect against.

Or are we missing something in the way we are implementing state token validation.

Yes, the key is in the details. From RFC6749:

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.

Once authorization has been obtained from the end-user, the
authorization server redirects the end-user's user-agent back to the
client with the required binding value contained in the "state"
parameter.  **The binding value enables the client to verify the
validity of the request by matching the binding value to the
user-agent's authenticated state**.  The binding value used for CSRF
protection MUST contain a non-guessable value (as described in
Section 10.10), and the user-agent's authenticated state (e.g.,
session cookie, HTML5 local storage) MUST be kept in a location
accessible only to the client and the user-agent (i.e., protected by
same-origin policy).

So the key is that the state value needs to be bound to the initiator user's session somehow. The RFC gives you a suggestion on how to do this.

The OAuth client(our server) on receiving the redirect URL would validate the state token, this is because [...]

This is where the state parameter comes in. You do not exchange the access code before validating the state parameter.

You validate the state by making sure it is a value that belongs to the user who initiated this flow. In the situation you described above, this should fail as the state belongs to the attacker and the current requestor is the victim.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.