OWASP Vulnerability Deep Dive: CSRF

Wednesday, October 30, 2013

Kyle Adams

514b2ac354098d84c07620f2591193b2

While OWASP has been around for a long time, and many security experts are aware of their top 10 web vulnerability report, I thought it would be beneficial to elaborate and share a bit more color on each one.  So this blog series will focus on some of the most common web attack vectors, how they are exploited, some examples, and finally how to prevent the exploit on your own applications.

For those who are not familiar, OWASP (Open Web Application Security Project) is an organization that helps web developers and security researchers understand the types of attacks that a site can expect to receive.  They have done a great job categorizing the various attacks and providing information on what they are. Every web developer would benefit greatly from reviewing this information so it is at the forefront of their minds while designing and coding for the web.

CSRF: What Is It?

So let’s start with one of my favorite attack vectors.  Cross-Site-Request-Forgery (CSRF).  CSRF is an attack that exploits the trust a website has for its users.  It all starts with authentication.  When you visit a website that requires a login, generally you are issued a session cookie.  This cookie is used to track you around the site after you login.  If it weren’t for this cookie, the site would likely require that you enter a username and password on every page (which isn’t practical). 

Another OWASP vector is called “session hijacking.” I’ll elaborate on this in another post, but for now, session hijacking is basically when an attacker somehow steals your session cookie and uses it for himself. Since that is the only way most sites generally track their users, if an attacker starts using your cookie, the site can’t tell the difference between you and the attacker.  Both users basically get the same level of access to the same data.  Stealing a session cookie isn’t always achievable, and that’s where CSRF comes into play.

In a CSRF attack, the attacker doesn’t need to actually obtain your session cookie.  Instead, he just needs to trick your browser into making a request to a site where you are already logged in, which will consequently also carry your session cookie.

CSRF: Prevalence

CSRF attacks are not extremely common in relation to other exploits, but they do happen and with a fair degree of regularity. This is because CSRF attacks are extremely powerful. They overcome much of the painful and difficult work of hijacking a user’s session, and boil the attack down to something so simple it works even if the user has flash, JavaScript, java, and Silverlight disabled. 

Even worse, it works in every single browser that renders images, and could theoretically also work in a text-based browser that downloads stylesheets or JavaScript. In effect, it’s the ultimate low-hanging-fruit, and is likely to be one of the first vectors an attacker will leverage if it gets the job done. Since it’s so painful to protect against, a huge number of sites on the Internet are still vulnerable to it.

CSRF: Example Attack

Let’s take a theoretical bank, “Insecure Bank International,” which provides a convenient web interface for managing your bank accounts. One day, you decide to log in to your account so you can send an electronic payment to your friend.  Once you log in, you now have a session cookie for the bank website, and are not required to log in again until some period of time later. You then issue a transaction to send funds to your friend.  In the background, a request is made to the server that looks like this:

http://fakebank.com/transfer.php?account=savings&dest=4363463634543343&amt=200.00

There are two interesting pieces of data in that request.  The destination account number, and the amount.  Note that this is a fairly simplistic example, and the viability of a CSRF attack relies on the target URL being relatively static in nature (predictable), which this one is.

Now if an attacker wishes to force you to send them $1,000 from your savings account, she could spend a lot of time trying to steal your session cookie so she can do whatever she wants.  Or, she can launch a CSRF campaign to explicitly force a single transaction and nothing else.  To do this, all she needs to do is get your browser to make a crafted request to the bank that looks as though you just asked it to transfer money.  So in this case, the attacker wants to get you to visit:

http://fakebank.com/transfer.php?account=savings&dest=111222333444&amt=1000.00

As you can see in this version of the URL, the attacker has replaced the destination account with her own account, and the amount with $1,000.  Because any request the user makes to “fakebank.com” will carry the session cookie along with it (and thus be authenticated), all the victim would need to do is type that URL into his browser and hit enter, which would cause the money to be transferred to the attacker.  Of course most users are smart enough not to follow such a link.

The easiest way to get a user to visit that URL unknowingly is to embed a resource in an unrelated page that points to it.  For example, let’s say the attacker knows you visit a forum on car restoration. They could sign up for an account, and reply to one of your posts, including an image of a cool new exhaust system. Unfortunately, the image doesn’t point to a picture of an exhaust system, but instead points to your bank and its transfer money URL.

<-img src=”http://fakebank.com/transfer.php?account=savings&dest=111222333444&amt=1000.00”->

So after sending your friend some money, you decide to go check up on your car forum posts.  You discover that someone replied to your post and quickly go take a look. The reply loads up, and you read it, slightly disappointed that the image of this revolutionary exhaust system didn’t load. 

What you don’t realize, is that the image isn’t intended to load, it’s intended to steal money behind your back.  The browser attempted to go fetch the image, but unintentionally told your bank to send the attacker money.  Since the resulting response from the bank was likely HTML, the image didn’t render.

CSRF: Flavors of Exploitation

There are tons of different flavors of this attack designed to overcome various limitations in the way a site initiates actions. For example, some sites won’t accept all the parameters in the query string (which is a good thing).  This means that an attacker needs to actually force a hidden form to post to a hidden iframe to launch the attack.

If a form post isn’t required, this attack can be launched with image tags, embedded object tags, stylesheet tags, imports in stylesheets, JavaScript tags, favicon redirects, etc. Other sites require some parameters to be set to values unknown to the attacker, which means he may have to brute force the URL to figure out the correct info.  It gets much more complicated from there, but the basic idea is the same.  Overall, unless you do something to protect from CSRF attacks, there is usually a way to craft one that will work, even if it’s fairly complicated.

CSRF: Prevention

The most commonly practiced solution to preventing CSRF attacks is something called a “CSRF Token.”  As mentioned before, the critical requirement for a CSRF attack to work is having a predictable URL to attack. You need to know exactly how to craft the fake request (within a few unknown bits) so that the server will accept it and perform the desired action. Embedding a large unknown unpredictable value in the URL makes it impervious to CSRF attacks by themselves. 

Generally to pull this off, you issue a second cookie along with the session cookie that contains a randomly generated string of characters.  You then have your webapp embed that cookie’s value in the URL and forms. When you receive a request, you verify that the random string in the parameters matches the one in the cookies.  Since the attacker can’t read the cookie value, they won’t be able to predict the URL, and won’t be able to launch a CSRF attack. For example:

http://fakebank.com/transfer.php?csrf=AHraFdsgHRBAE&account=savings&dest=111222333444&amt=1000.00

The attacker doesn’t know the value of the “csrf” parameter and, therefore, can’t create code to fake it.  The only way for the attacker to obtain the CSRF token would be by using a cross-site-scripting (XSS) vector to extract it from the source, which obviates the need for CSRF in the first place.  If you can launch XSS, you don’t need to use CSRF.

CSRF: Conclusion

Adding CSRF tokens throughout the application on every URL that takes an action on the user’s account is a great defense. The problem is that it is extremely time consuming and painful to integrate into a large application. Fortunately, many browsers are now adding native protection for CSRF attacks, but it may be a while before they are extremely effective at it. 

Bottom line, if you have a web app, it would be wise to consider how you will protect it against CSRF attacks until they are fully handled by the browser.  Alternately, some security solutions have built-in protection for such attacks and can help make protecting your applications from common attack vectors far easier.

Cross Posted from Juniper Networks

Possibly Related Articles:
5933
Vulnerabilities Webappsec->General
OWASP CSRF vulnerability Cross-Site-Request-Forgery information
Post Rating I Like this!
The views expressed in this post are the opinions of the Infosec Island member that posted this content. Infosec Island is not responsible for the content or messaging of this post.

Unauthorized reproduction of this article (in part or in whole) is prohibited without the express written permission of Infosec Island and the Infosec Island member that posted this content--this includes using our RSS feed for any purpose other than personal use.