3

I'm having a really hard time understanding why the state should be used to protect against CSRF at the OAuth 2.0 login flow.

Imagine I have an Authorization Server with a legitimate client registered with the client_id of my-app-123 and the redirect_uri registered to https://my-front-end.com/login-callback

Okay, my front-end application can redirect the user to the authorization endpoint:

https://authorization-server.com/.../authorize?client_id=my-app-123&scopes=openid&redirect_uri=https://my-front-end.com/login-callback

Nice, the Authorization Server Login Page appears, the user logs in and gets redirected back to my front-end app which would then use a BFF to issue a token. The BFF would receive the code, exchange it for an access_token by using the secret and the authorization code. The BFF would then create session and associate the session with a access_token (in a map on memory, on Redis, whatever..) and set the session on the front-end which would then redirect the user to a logged page on the website. Everytime the front-end communicates with the BFF, it uses the session and then the BFF uses the access_token to communicate with the backends.

How is this flow vulnerable to CSRF attacks without the state parameter? Maybe I'm missing something or maybe I'm lacking knowledge on how CSRF works. Let me explain bellow:

  1. Malicious Web Page tricks the user to initiate a Login (redirecting it to https://authorization-server.com/.../authorize?client_id=my-app-123&scopes=openid&redirect_uri=https://my-front-end.com/login-callback)

  2. User logs in

  3. Authorization Server redirects to the actual legitimate front-end

How is this vulnerable? I really cannot understand how would the malicious web page could get any information out of the user or execute any action on his behalf.

Could someone explain to me and point out where I am missing things?

1 Answer 1

3

To perform a CSRF attack, assuming authorization code grant type and no state parameter, an attacker could initiate an authorization flow and then grab the authorization code before completing the OAuth redirect request.

Then, the attacker can try to trick a victim into clicking on a link to complete that OAuth redirect with the attacker's code. If they succeed, the relying party (i.e. your app) would then request access tokens for the attacker's resources and associate them with the victim's session. This might result in, for example, the victim uploading sensitive data to resources owned by the attacker.

The state parameter defends against this by binding the users session to the original authorization request. For example, you could set the state parameter to be the sha256 hash of the user's session ID. Then, when processing the redirect, you check that the state parameter matches the sha256 hash of the user's session ID - if it doesn't then you reject the request.

This is explained in a bit more detail in the RFC.

3
  • Hmmm this made some sense. Then the attacker could issue an authorization code of his account and then trick the legitimate application to issue an access_token to his account. The user would then be using the attackers "account" and perhaps be uploading his stuff to the attacker's account. If the state was present, the application would reject the request and not issue an access_token. Is that it?
    – Matheus
    Commented Aug 14 at 13:18
  • 1
    Exactly. Victim might then upload sensitive data. Or maybe download malicious files, etc.
    – andycaine
    Commented Aug 14 at 13:20
  • Very helpful, andy. I was getting crazy on not being able to understand how the attack would work. I read the very same RFC you referenced, but somehow I missed it.
    – Matheus
    Commented Aug 14 at 13:25

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .