The client must use state parameter to block CSRF attack against the redirect URI. Without the state parameter client browser/server has no way of knowing whether the incoming GET request with the authorization code was caused by a 302 redirect it initiated or by user clicking a hyperlink in a malicious email / blog.
Steps to create a CSRF attack
First the actors in oauth flow
- Simpleuser - the resouce owner
- Mr thief - wants to access Mr simpleuser's phtos on personalphotos.com
- personalphotos.com - client application, a service where user can create personal albums with photo editing capability.
- google drive - resouce server . this where personalphotos.com saves the edited photos.
The steps (without using state )
Assumption is that simpleuser is allready logged in to personalphotos.com.(ie localsession has been created by personalphotos.com webserver for simpleuser. (CSRF attack is also called session riding as existing user session is exploited)
- Mr thief visits personalphotos.com and intiates authorizing personalphotos.com access to his google drive.
- personalphtos.com will redirect Mr thief's request to google auth server.
- Mr thief will provide his google credentials and authorize personalphots.com access to his google drive.
- After authenticaion and authorization is complete,Google auth server will redirect to pesonalphotos.com redirect url with auth code , for example the redirect url may look like https://personalphotos.com/callback?code=mr_thiefs_code
- Mr thief intercepts and saves this URL. (note that intercepting is important as auth code can be used only one time to get tokens)
- Mr thief gets mr simpleuser to click this url from mr simpleuser's browser (link could be sent by email / blog)
- Note that simpleuser may be clicking on some random image which actually leads to a get request to this url.
- personalphotos.com does not have way to know that get request is becuase of genuine redirect or some other source.
- Simpleuser who is allready logged in visits the url .
- mr_thiefs_code will get exchanged with mr thiefs access token and personalphotos.com saves this access token as mr simpleuser's access token.
- now any upload of photo by simple user will reflect in account of mr thief.
The steps (with using state and hence preventing CSRF)
- Simpleuser visits personalphotos.com and intiates authorizing personalphotos.com access to his google drive.
- personalphotos.com server creates a random state ( simple_users_state_xxyyy ) and binds it to simpleuser's authentication session .
- personalphtos.com will redirect simpleuser's request to google auth server with client id and state .
- After authenticaion and authorization is complete,google auth server will redirect to pesonalphotos.com redirect url with auth code and state . The redirect may will look like
- https://personalphotos.com/callback?code=simpleuser_code&state=simple_users_state_xxyyy
- Mr thief visits personalphotos.com and starts the process of authorizing personalphotos.com access to his google drive.(with random state mr_thiefs_state_x1y1z1)
- personalphtos.com will redirect Mr thief's request to google auth server.
- Mr thief will provide his google credentials and authorize personalphots.com access to his google drive.
- google auth server after authenticaion and authorization is complete will redirect to pesonalphotos.com redirect url say https://personalphotos.com/callback?code=mr_thiefs_code&state=mr_thiefs_state_x1y1z1
- Mr thief intercepts and saves this URL.(note that intercepting is important as auth code can be used only one time to get tokens)
- Mr thief gets mr simpleuser to click this url from mr simpleuser's browser (link could be sent by email / blog)
- Note that simpleuser may be clicking on some random image which actually leads to a get request to this url
- Simpleuser who is allready logged in visits the url .
- personalphotos.com will compare the state from request parameter mr_thiefs_state_x1y1z1 to mr simpleuser's state saved in his session which is simple_users_state_xxyyy
- the state will not match !!
Sequence Diagram (shows oauth flow with state handling)
Note that storage method of state depends on app type
- For Regular Web App - Cookie or session (the webserver + browser togather make the client )
- For SPA - Local browser memory
- For Native App - Memory