7

I'm using csrf protection in my web app.

Now I'm planning to trigger a OAuth2 Authorization Code Grant workflow, starting with a static template opened in a new browser window using window.open(myOAuth2StartEndpoint?oauthstuff&state=mystate).

But as in this case the mystate variable is exposed inside a static href tag when starting the workflow, I'm wondering if it's dangerous to just expose my default csrf token as mystate? I can make a csrf check inside myOAuth2StartEndpoint, so the token is not exposed for free, but is this enough?

If not, are there recommendations for how to handle this case?

bebbi
  • 171
  • 1
  • 2

2 Answers2

3

Disclaimer : Couldn't find any reference on the subject so I will use a questionable tool called "logic". If someone find any good reference, please add them.

CSRF is dangereous

There is no doubt about it and OAuth2 is no exception. In fact, there are multiple ways that you can exploit CSRF attack while using OAuth2. The reason is that there are multiple message that are sent that could be use to trigger a CSRF attack. The section OAuth2 Spec Section 10.12 gives a good overview of what you could do with CSRF

But, let's look at what happen in details when a user want to login using OAuth2. In our example, we will have the following actors :

  • The user (you and your browser)
  • The attacker (usually a malicious website)
  • The client (web application you are using)
  • The provider (oauth2 server that authenticate the user)

Then, let's look at what happen from the user point of view when he tries to authenticate with the provider.

  1. The user click a link on the client website and get redirected to the provider authentication form
  2. The user authenticate with the provider and get redirected to the client website where he gets authenticated too, automatically

Where can we attack?

From the user point of view, it's just 2 simple steps but there is multiple places where you can attack it. One of the root problem here, is that often the OAuth2 provider will redirect you automatically, if you are already logged in. A good example, is stackoverflow. See this answer for details :

OAuth2 Cross Site Request Forgery, and state parameter

So the different attacks are :

  1. An attacker can replace the authorization code with his own to make you login into his account instead of yours. Might look like a crazy idea but if you decide to enter some confidential information in his account, he now has access to it. Ex.: bank information

  2. An attacker can generate a valid provider link on his machine and then he serves it to you, if the provider is redirecting automatically then you will be logged in to the service the attacker want to attack.

  3. The attacker make you generate a valid provider link from the client website (only works if the link is generated via a post/get on a static url), then if the provider is redirecting automatically you will be logged in to the service of the attacker want to attack.

How to protect against them?

Simple, you just need to pass your CSRF anti-forgery token in the state parameter of OAuth2 to protect against #1 and #2. Then, to protect against #3, you need to make sure that the link cannot be generated without the user interaction, meaning protect that link with CSRF protection. But back to #1 and #2...

By including, a CSRF token as the state, you will defeat those attacks as it will be impossible for the attacker to serve you links that you didn't generate yourself. A simple implementation of a CSRF token is a random number that is stored in the session and then included in every form sent by that by a user. If the form contain the token, the client consider it as valid. If it doesn't contain it, then the client assumes that the request is invalid.

Usually, that CSRF token is only accessible to the user/browser and the client, but in the case of OAuth2, more parties get access to it. To understand what to do, we need to know which are these additional parties.

The Answer : Just send the token

So, in that case, the token will be known to

  • The client (the one who created it)
  • The user
  • The provider

It's a simple round trip over HTTPS. An attacker cannot insert himself in that conversation so you don't need to worry about that.

Do you need to protect the token against the provider?

No. If the OAuth2 provider is malicious you have already lost. He doesn't need your CSRF token to take over all your accounts if he wants. When you chose to use OAuth2, you basically made him god of all your user accounts.

Conclusion

Don't worry too much how you send the CSRF token; just make sure you send it. Also, the fact that it's sent as a url parameter would be another point to worry for a permanent password but since those tokens are temporary is shouldn't be much of a problem.

Gudradain
  • 6,941
  • 2
  • 26
  • 44
0

state is information that is passed by the RP (resource provider) to the IP (identity provider) and it is expected that the IP will send the same information back.

In my case I used the state in my JavaEE OpenID Connect implementation as the URL to the application relative to the URL that was originally requested on the RP before the OP login screen is shown.

I protected it using a symmetric cipher then base64url encoded it. Along with a validation that it is a valid URL and is relative to the root of the application when resolved against the root of the application. The symmetric key is randomized and not passed outside of the RP.

If I wanted a more secure implementation (but will restrict to IPs that support nonce) I would encode both the source URL and a nonce together and ensure that the decoded nonce value is extracted. The nonce can act as a salt.

Additional note

Other IPs may send a different state value back to the RP. Though that usually implies that there are non-standard data that are passed by the RP to the IP and they understand each other. For example a secondary state can be passed and depending on the IP processing it can send the other state if needed.