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:
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
)User logs in
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?