Cross Site Request Forgery (CSRF)

Christopher Makarem
IOCSCAN
Published in
4 min readNov 8, 2018

Cross site request forgery (CSRF), also known as XSRF, Sea Surf or Session Riding, is an attack vector that tricks a web browser into executing an unwanted action in another web application to which a user is logged in and has an active session in.

CSRF attacks are usually performed using phishing attacks to trick users into clicking on specially crafted web pages that will use a user’s preexisting session (usually in the form of saved browser session cookies) to forge a request to another web application. As the victim is already authenticated to the targeted web application at the time of the attack, it is impossible to distinguish legitimate requests from forged ones.

What makes CSRF attack so dangerous is that the attack works without user action on the malicious web page. Although it can be set up so that the user must interact with the malicious page to start the CSRF attack, most CSRF attacks can be automated via javascript meaning that once a user clicks on a link to the malicious page, it is all over. Even if the user realizes his mistake and immediately closes the page, the attack will have already been carried out.

CSRF Workflow

Examples of CSRF

CSRF is commonly used to spoof both POST and GET http requests to secure servers. We will first look at a GET request example.

GET Request
A typical GET request for a bank transfer might look like this:

GET "https://bank.com/transfer.do?account=LegitUser&amount=$100" HTTP/1.1

A hacker can modify this GET request slightly to transfer the $100 to his account instead:

GET "https://bank.com/transfer.do?account=Attacker&amount=$100" HTTP/1.1

This request can simply be embedded in a hyperlink on a webpage:

<a href="https://bank.com/transfer.do?account=Attacker&amount=$100">Click Me!</a>

This request can also be written as JavaScript so that the request will be sent without requiring the user to click on any hyperlink:

const Http = new XMLHttpRequest();
const url='http://bank.com/transfer.do?account=Attacker&amount=$100';
Http.open("GET", url);
Http.send();

POST Request
POST requests operate a bit different than GET requests in that POST requests cannot be embedded in a hyperlink <a> tag in the page. The only allowable source of a post request is in a <form> tag that can be automatically submitted via JavaScript.

<body onload="document.forms[0].submit()">
<form action="https://bank.com/transfer.do" method="POST">
<input type="hidden" name="acct" value="Attacker"/>
<input type="hidden" name="amount" value="$100"/>
<input type="submit" value="Click me Please!"/>
</form>
</body>

CSRF Mitigation

Server-Side
The best way to prevent CSRF attacks is to prevent them from occurring on the server-side. Since it is impossible to guarantee that every user will follow the best-practices, to secure a site from forged requests, it is up to the web application developer to protect their database.

The primary method of securing a web application against a CSRF attack is by generating a secure token that is uniquely tied to the user’s session cookie. (If you think of the cookie as a password, then the token will be the hash of the password). Then in order to send a valid request to the web application, the request must be accompanied by the secure token as a header in the HTML request. The server will be able to compare the cookie with the token (via hashing) and if they match up, then the request will be authenticated. This destroys a CSRF attack because the attacker’s malicious request has no way of determining the secure token and will not be able to pass it in the header of the HTML request it is trying to forge. When the request is received by the target server, since there is no accompanying secure token, the request will be rejected.

Another option would be to mutate the session cookie value upon each request to the web application. This means that the session cookie is only allowed to make one request before it must be changed. When a CSRF attack occurs, the same cookie will be used twice, since the attacker’s site will be unable to receive an updated cookie and thus the legitimate server will reject the request.

A simpler option that is best paired with one of the above options would be to reduce the amount of time a user’s session is active. If a session is active for only a few minutes, it reduces the risk that a users will visit a malicious site in that time window. But if a session is allowed to exist for hours, then it is likely that the user may forget or not even realize they are still logged in and increases the chance the user will visit a malicious site in the extended time frame.

Client-Side
Although Server-side mitigations are preferred, some sites are too old or some developers don’t care enough to implement those mitigation, thus it is in the best interest of the user to always follow these best practices:

  • Logging out of sites when you are done using them or before visiting other sites.
  • Not allowing browsers to remember passwords
  • Clear cookies when closing the browser (some sites use persistent cookies that will keep a user logged in, even if the browser is closed)

--

--