Understanding and Validating Cross-site Request Forgery

Screen Shot 2013-06-11 at 8.49.46 AM.png
 
[Corresponding slides available here. ]
 
Cross-site Request Forgery--often written CSRF and pronounced "Sea-surf"--is a common web application vulnerability that's far too misunderstood. Having participated in countless information security interviews over the years, it's stunning to see the number of experienced professionals in our space who struggle even to describe how CSRF differs from XSS--let alone how to validate it or defend against it.
 

This article will discuss the basics of the vulnerability, how to validate that it's present in real-world applications, and some common ways of defending against it.

 

CSRF is currently (2013) #8 on the OWASP Top 10 list of web application vulnerabilities, and it can be described as follows:

Cross-site Request Forgery is a vulnerability in a website that allows attackers to force victims to perform security-sensitive actions on the Internet without their knowledge.

Let's try to unpack that.

 

 

First, the vulnerability is on the server side, not on the client side. Second, it involves an attacker forcing a victim to perform a security-sensitive action. And finally, victims usually don't know the attack is taking place until much later--if ever.

 

 

 

So what constitutes a "sensitive action"? Two things: 1) it has to result in a change, and 2) it has to be a change that matters. Examples include changing someone's salary, transferring money at a bank, updating someone's password, etc. Non-changes don't matter, and changing the background color of a webpage probably doesn't matter either.

 

 

 

Forcing a user to execute these actions is done through the manipulation of their browser. There are several types of functionality that browsers execute for us when we visit a webpage--all without our knowledge. When visiting cnn.com, for example, there may be 100 different image requests that are performed by your browser, and none of them are the result of explicit action by the user.

 

 

 

Automatic image loading, as well as script execution, work to the advantage of the attacker in the case of CSRF. With these types of automated actions, your browser isn't just requesting those resources on your behalf: they're actually sending your cookies for that resources domain out with each request. And cookies are proof to the receiving website that you are you.

 

csrf.png

Image from linuxforu.com

 

 

So we basically have a situation where your browser is constantly doing things on your behalf--such as sending requests for images and executing scripts--and your authentication information (cookies) are being sent along with each request. And if you spend a couple hours browsing online this has probably happened to you literally thousands of times.

 

So, why is this a problem? Because if you visit a malicious website, they can create an image that looks like so:

 

Screen Shot 2013-06-12 at 10.13.05 AM.png

 

 

In other words, just by visiting some random website hosting cat pictures, your browser could attempt to load that image--thereby resulting in you transferring money to an attacker. How could they do that without your authorization? That's the problem--they had your authorization, because when you sent a request to somebankfrom1999.com you also sent your cookie for that site as well. And cookies are basically passwords for web applications.

 

So, that's bad (thanks Egon).

 

One thing that's interesting about this is that it's an abuse of trust that makes this possible--just like with XSS--only the opposite. With Cross-site Scripting you have the client running malicious JavaScript because it was served by a server it trusts, and with Cross-site Request Forgery you have the server executing sensitive actions because it was sent by a client it trusts.

 

Validation

 

My background is in vulnerability assessment and penetration testing, so I've seen a lot of real CSRF and a lot of what <em>looks like</em> real CSRF. Here are three ways to validate that you have the real thing. In order to have real CSRF you must have all of the following:

 

  1. You can make a change using it
  2. That change is sensitive
  3. The request that makes the change isn't unique

I like the acronym "CSU" to remember those three. So, if a tool tells you you have CSRF because it pattern matched off of some sensitive name--like transfer.aspx, but you're not able to make a change to anything using that page or request--it's not a real CSRF vulnerability. It's also important to realize that the change must happen in a single request, i.e. it cannot be stopped by a CAPTCHA, or an additional authentication prompt, etc. If you can't make a change--and make it without hitting a deliberate interruption--then it's not CSRF.

 

Similarly, if you can make a change to the page, but it's not to something that the business cares about--you also don't have a CSRF vulnerability. Notice I said something the business cares about. CSRF is a vulnerability that highlights the fact that the business knows best when it comes to impact. If you tell them that someone could do "X" to "Y" within the site, and the business knowledgably responds that it's not an issue for them--then it's not a significant vulnerability.

 

Finally, both the above need to be true in addition to the request that makes it happen being non-unique. What does that mean? It means that the request that triggers the sensitive change (qualified above) must be able to be triggered by an attacker in a trap that is laid for the victim--either via an auto-submit form field or via an image load--etc. If such a request would fail due to defense on the server side--then you also don't have a vulnerability.

 

So, before you write someone up as having a CSRF vuln, you need to be able to show that all three are true. Tools are great at pointing you in the right direction, but remember that you may need to validate all the steps above before you submit or accept CSRF as a valid vulnerability.

 

Attack Vectors

 

CSRF attacks work by getting users' browsers to unknowingly perform undesirable and sensitive actions. This happens by them arriving at a given website where malicious content exists, which is then executed by their browser. There are two main ways of doing this:

 

  • Inserting malicious content into an existing site the victim will visit, e.g. a malicious image tag or form submission that executes on page load
  • Creating a page of your own, hosting that malicious content there, and then enticing the victim to visit your own page

In both cases the content in question will be executed and the actions will be performed.

 

Common Defenses

 

We talked about validating CSRF, and the key to defense lies in a couple of those checks, namely the ability to make a change in one request, and the ability for an attacker to build a request that will work on the server-side without being rejected for non-uniqueness.

 

Let's take a look at those.

 

  1. You can defend your application by adding an additional step, or steps, to complete sensitive actions. This could be the completion of a CAPTCHA, an additional authentication challenge, or even just a confirmation that cannot be completed in an automated fashion. The key is stopping a single request from performing the action.

 

2. Another and perhaps more common way is to ensure that all requests to perform sensitive actions include unique identifiers that only legitimate clients will have, which prevents attackers from building valid requests that are then launched by unknowing victims. This usually takes the form of implementing a nonce within a hidden field of the form being sent.

 

Combining XSS and CSRF

 

The nonce defense mentioned above works because a valid request to the page, which yields a valid nonce, is required in order to build a legitimate request to the application. XSS can potentially be used to fetch the nonce, however, which can then be used in the subsequent CSRF request.

 

This is what the Samy MySpace worm did. The Samy worm was code on a user's profile that, when visited, added Samy as the visitors friend and then copied the code to their profile. But MySpace had a CSRF request--the nonce requirement. Samy bypassed that by pulling the nonce first via XSS and then feeding that value into the CSRF request.

 

Resources and Links

 

 

Summary

 

Knowing the basics of Cross-site Request Forgery and how to validate that it's been found in real-world applications is a a good minimum for today's application security professionals. Remember the CSU acronymn for validation: The request in question must be able to make a change, that change must be sensitive, and must be non unique.

 

For any comments or questions, please contact me at daniel.miessler@hp.com. 

 

Tags: appsec| CSRF| infosec
Labels: appsec| csrf| infosec
Comments
Ashok Sharma(anon) | ‎10-12-2013 10:00 AM

Thanks Daniel for such a wonderful explanation of CSRF.

You mentioned correctly that this attack is commly mis-understood by many in security domain.

Will look forward for more stuffs from you.

Regards

Ashok

Leave a Comment

We encourage you to share your comments on this post. Comments are moderated and will be reviewed
and posted as promptly as possible during regular business hours

To ensure your comment is published, be sure to follow the Community Guidelines.

Be sure to enter a unique name. You can't reuse a name that's already in use.
Be sure to enter a unique email address. You can't reuse an email address that's already in use.
Type the characters you see in the picture above.Type the words you hear.
Search
Showing results for 
Search instead for 
Do you mean 
About the Author
http://www.danielmiessler.com/about
Featured


Follow Us
The opinions expressed above are the personal opinions of the authors, not of HP. By using this site, you accept the Terms of Use and Rules of Participation.