Cross Site Request Forgery
With an increasing number of applications being developed, complexity of those applications is also rising. It is only logical for developers to reuse old snippets of code and api in new applications to make the application less complex and more modular.
But in most cases they fail to properly secure the api endpoint. Which explains why Cross Site Request Forgery is on 5th position in OWASP Top 10 Web vulnerabilities
Overview
CSRF is an attack that makes the end user execute unwanted actions from the authenticated web application.
Consider the example of a banking application.
In the banking application, users can log into their account and perform various tasks such as checking the balance, making a transfer, ordering a cheque etc. If the user asks to initiate a transaction, the application will ask the user for the recipient account number and will form the request to the backend containing details sufficient to initiate the transfer such as, sender account number, recipient account number, amount and time.
So, typical flow would be:
User will log in -> Open Dashboard -> select initiate transfer -> Application forms the request -> request is forwarded to the backend -> backend processes the transaction
Consider that in this scenario, For the authentication, the application uses cookies which are stored in the user’s browser. So, with the request, an authentication cookie is also sent which helps the backend identify if the request is indeed made by the genuine user.
Now, if a malicious actor wants the innocent user to transfer $10,000 he will craft a csrf payload and send it to the victim via banking application’s messaging functionality. So, once the message is viewed by the victim, the underlying malicious payload grabs the authentication cookie and initiates the transfer of $10,000 to the attacker's account.
For the payload part, it can look like following:
<html>
<body>
<form action="https://vulnerable-bank.com/transfer.php" method="POST">
<input type="hidden" name="sender_account" value="11111" />
<input type="hidden" name="receiver_account" value="22222" />
<input type="hidden" name="amount" value="10000" />
</form>
<script>
document.forms[0].submit();
</script>
</body>
</html>
Here, document.forms[0].submit(); in the script tag makes sure that the malicious request to initiate the transaction is made as soon as the message has been loaded by the victim
We will see the demo of a typical CSRF attack with Portswigger Web Academy’s CSRF lab.
Our task is to craft an HTML payload to perform a CSRF attack that when processed will change the viewer’s email address.
We are given a user account with username wiener and password peter.
Click on “Access the lab” to spawn the vulnerable website.
As we can see, this is a blog page, we are presented with several options to navigate, such as navigating to my account page, home page and the exploit server.
Open the My account page as it is more likely to contain the functionality to change the email address:
Enter Username and password to login
Now we are presented with the functionality to change the email address and our current email address is wiener@normal-user.net.
Let’s try changing it to asd@thelaw.com
To better understand the requests made by the application, we can open the burpsuite and intercept the requests
We have used the email changing feature to change email to bsd@thelaw.com and intercepted the request. Taking a closer look at the request, we can see that it is a POST request to the API endpoint /my-account/change-email
POST data contained in the request is email=bsd@thelaw.com
Now we can use this information to craft an HTML CSRF attack payload to exploit. Payload can be generated by hand, but with complex applications, it can be overwhelming, so we are going to use CSRF payload generator tools. While Burp Suite’s CSRF functionality is extremely useful, it is available only in Burp pro version and not in community.
If you have pro, right click on the request, select engagement tools and then click on Generate CSRF Poc. Also click on the auto-submit script and click on “Regenerate” to reflect the changes inside HTML, you can copy the HTML with the “Copy HTML” button and use that payload.
To exploit CSRF without purchasing burp pro, we can use Appsec website’s CSRF tool to generate payload. Go to http://online.attacker-site.com/html5/csrf_generator/csrf_poc_gen.html
Add the URL with the endpoint. Then add the parameter email with the value of the email address you want the value to be. Make sure that request method is POST and click on generate.
Payload generated should look like this:
Now we need to modify this payload to auto execute. For auto execution, remove the line with
<input type=’submit’ value=’Go!’ /> and add the following snippet
<script>
document.forms[0].submit();
</script>
Modified payload should look as following
Copy the generated HTML and get to the vulnerable website and click on Go to exploit Server
Copy the HTML snippet between body tag and paste it to the Body section of the exploit server, replacing Hello, World!
And Deliver the exploit to the victim. Once loaded, victim browser will make the request to endpoint /my-account/change-email to change the victim email address to pwnd@thelaw.com
You can play around with many more of the CSRF labs offered by portswigger web security academy to learn more.
Countermeasures
As Cross Site Request Forgery is getting more and more prevalent, several web development frameworks have built in CSRF protection. To have the best protection, check if the framework you’re using has built in CSRF protection.
If not, Add CSRF Tokens to all request that work with state changes as well as validate CSRF Tokens on backend.
Depending on the state implementations of your application, either use synchronizer token pattern or double submit cookies.
You can refer to OWASP CSRF Protection Cheatsheet to make sure you have enough protection implemented before deploying the application.