CSRF stands for Cross-Site Request Forgery. OWASP ranks this in its TOP 10 common vulnerabilities in web applications. In this paper, I aim to explain what actually it is. From the previous post, we learned that every click on the Internet is responsible for making one or multiple HTTP requests behind the veil; even mere loading a document (visiting a link) sends at least a request.
Consider you’ve an account on ABC, and you want to delete your account. To do this, you don’t merely need to click on a button saying ‘DELETE’, but ultimately, you need to send a request to the server. Suppose, this request is responsible for the deletion of account:
POST /DeleteAccount HOST: ABC Cookies: random confirm=1
Due to stability purposes, it was intentionally made possible to be able to send requests cross sites. This means that you can send the same request from ABC while being on DEF; hence the name. The behavior, however, challenged Same Origin Policy but it was assumed that only GET and POST method types should be safe, therefore, forging requests cross-sites, under normal circumstances, was only possible if the request method wasn’t other than a GET or a POST.
Originally, there was no catch to this and HTTP Requests initiated in CSRF attack, sent all the necessary contents without any sort of difficulty. However, this has changed a bit since the Chrome Update in 2018.
Host this HTML on your website and click on Submit button:
<html> <!-- CSRF Demo By Hunting Reads --> <body> <form action="http://huntingreads.com/wp-login.php"> <input type="submit" value="Submit request" /> </form> </body> </html>
OR SIMPLY CLICK ON THIS BUTTON
This will send a GET request to HuntingReads and you’d be visiting homepage. Bear in mind, this is harmless
There are number of ways to prevent this attack and one of the good ways is to send a random token with a state changing HTTP request, without which, the request should fail. So the above request containing a CSRF token would look like this:
POST /DeleteAccount HOST: ABC Cookies: random confirm=1&CSRF_Token=aRandomValue
The CSRF Token should be properly validated on server side, and should be unique to the account in such a way, that CSRF token on account A shouldn’t be valid in account B. This is a nice way to protect against CSRF attacks, although, I’ve noticed developers also tend to protect against it by verifying Referer header. This header was never meant to work as a security feature and therefore should not be treated as such. CSRF prevention that verify Referer header is very easily bypassed.