Cross Site Request Forgery (CSRF) attack on OAUTH2 protcol

by hash3liZer . 11 September 2018

Cross Site Request Forgery (CSRF) attack on OAUTH2 protcol

OAUTH2 is an authentication protocol, used by services to act on behalf of the user, allowing them to attain user information from the authentication server if so allowed by the user. This provides scalability for the client applications but if not properly configured could present security risks. One of these risks is Cross-Site Request Forgery (CSRF) which if properly exploited can be used to gain access to a victim's account.

Various applications that come up with OAuth facility links the OAuth credentials with the actual account and to some extent, provides the actual account API as well. Thus, if an attacker can make the victim login to his account, the attacker's account will be linked to the victim's account.

To understand the attack, one does have to have a grip on how it works. Here the following terms that we are gonna use here:

  • Client: The Application that is willing to acquire user's data.
  • User: It's us.
  • Authentication Server: The server which has the information like facebook, google etc.
  • Resource Server: From where data will be retrieved.

OAuth Flow:

First the user will click connect button which in result will send the user to a redirection link like this:

GET https://client.com/auth/google

Response: (Authorization Grant)

302 https://authorizationserver.com/authorize?response_type=code&redirect_uri=REDIRECT_URI&scope=SCOPE&client_id=AAA

The User will be redirected to authorization server where the user authorize the client to access his data. Upon successful proceedings, the user will be redirected back to the client with a code.

302 https://client.com/handle_code?code=CODEAAA

The client will take to code and send to Authorization in exchange of an access token.

POST https://authorizationserver.com/token "code=CODEAAA"
Response:
200: {access_token: 'abcToken'}

The client will take the token and send it to Resource server which provides the client with user data.

GET https://resourceserver/token/(abcToken)
200: Data

The problem lies at step 3 where the code is sent back to the client. There's nothing defined given at the step that could verify if the code is intended for the current user. Hence, a malicious user could create a dummy account and stop the process at this step, copy the code parameter and make the victim link his account with attacker using CSRF.

What a normal OAUTH should look like:

oauth

Steps to reproduce the attack:

First, we are gonna act on the behalf of the attacker:

  1. Setup a proxy and initiate the OAUTH connection by clicking the connect button.
  2. Authorize his account.
  3. Stop the request at this step and copy the link:
  4. https://client.com/code?code=ABCCODEOOO
  5. Drop the above request and send the link to the victim.

On Victim's behalf:

  1. Click the link.
  2. Client will take the code, a valid session will be generated and his account will be linked to attacker's account.
  3. Attacker login using the linked dummy account to gain access to victim's account.
oauth attack

Implicit Grant Attacks:

They are pretty much easier to exploit than code authorization attack. Access token is directly sent at step 3 which makes more vulnerable.

Mitigation

A state parameter should be implemented at step 2 whose value is some random generated hash. The state parameter is reflected back in step three like this:

https://client.com/code?code=ABCODOO&state=RANDOM_VALUE

The randomness of state parameter is important to make it less guessable. If the value can easily be guessed, then there's no use of providing the state parameter at all.

But wait what if the attacker can use his own state parameter value. The user is still vulnerable. There should be a session cookie at step 1 which will verify that if the state parameter belongs to this user and even not expired.

To protect from CSRF:

  • CSRF at logout and Login Buttons.
  • State parameter with a random hashed value at step 2 and 3.
  • Sessions to verify CSRF tokens.

Reversing the Attack:

Previously, the reproduction steps were for linking the social account with the victim's actual account. What if the process can be reversed. i.e. actual account being linked to social account. This presents a problem at login and logout functionalities.

An attacker would create a dummy account on target site and due to the lack of CSRF at both forms, he will make the victim login to his account by setting up a faulty page. Thus, it's necessary to provide CSRF at both places. Well, in practical, many website choose to omit this.

Steps to reproduce:

The reproduction steps are rather simple for this attack.

  • Attacker create a forged page something like this and send to victim:
<html><head>
<title>POC</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.js"></script></head>
<body><img src="https://target.com/logout" />
<form id="loginForm" method="POST" action="https://target.com/login">
<input type="text" name="username" value="dummyuser" />
<input type="password" name="password" value="dummypassword" 
</form>

<script>
    $(document).ready(function(){
        $('#loginForm').submit();
    });
</script>
</body>
</html>
  • Victim open's the link, get logged out and logged in as attacker.

Sometimes, on clicking the logout button will get logged out at all. So, be sure whether you need to send a request at logout url or not.

Thus, you saw how a simple CSRF in OAUTH could lead to an account takeover. There are some other flaws in OAUTH as well, we will talk about it later in upcoming blogs. I hope you've enjoyed the post.