Cross-site hacks and the art of self defence
The new browser wars
Hackers can force your browser to send requests to any site they want. It's not even hard - all they have to do is get you to view an email or a web page.
Unless the site is specifically protected against this - and almost none are - then attackers can make your browser do anything you can do, and they can use your credentials and your access privileges. They can do things like set preferences, create payees and change passwords.
Generally, browsers stop cross-site communication by following the "same-origin policy". This rule is pretty simple: if your site has a different origin - protocol, domain, and port don't all match - you aren't allowed to access information from or send requests to the other site. Without this simple rule, there would be no security on the internet. Every website could access data from every other one - you'd need a separate web browser for every website.
Unfortunately, the same-origin policy is nowhere near airtight. Attackers don't even need an exploit to bypass it. They can simply embed an IMG, SCRIPT, IFRAME, or FORM tag that references the targeted website in an HTML page. When the victim's browser renders this tag, it generates a request and sends it to the targeted website - right around the same-origin policy. This is a feature of all browsers - it's used by many applications to grab images from other sites and to post from data to services.
Attackers can use this loophole to forge requests that appear to be coming from a legitimate user. These are called cross-site request forgeries, or CSRF, for short. Take a look at the old CSRF attack on Netflix, below.
<img src=http://www.netflix.com/AddToQueue?movieid=70011204 width="1" height="1" border="0"> Attackers can submit forms on your behalf as well. <body onload="document.forms.submit()"> <form method="POST" action="https://bank.com/transfer.do"> <input type="hidden" name="account" value="123456789"/> <input type="hidden" name="amount" value="2500"/> </form>
The attacker can post this image tag anywhere - a blog, a wiki, a website, even an email message. Anyone who accidentally browses a page containing the attack while logged into Netflix will have a movie silently added to their queue.
More complex attacks involve a sending series of requests and delays, allowing the attacker to execute a series of actions in a row. In a strange way, a CSRF attack is a sort of program that executes web instructions on behalf of the attacker.
Imagine your browser suddenly turned evil and started trying to mess up your life. What could it do? It might raid the email account you're currently logged into. Maybe it would go after any bank accounts and healthcare sites you're using. Did you click "remember my login" on any websites? Guess what, your renegade browser is logged in and can take over those accounts.
And what if you're at work or connected to the virtual private network? Your browser can go after the corporate portal. Do you have single sign-on? That means you're logged into every web application on your intranet, and your renegade browser can go after any of them.
Using CSRF, an attacker can attack all of these targets and can do just about anything you can do through your browser. All these attacks can be done remotely and basically anonymously.
OK, so what can you do to protect yourself? First, don't stay logged into websites. You have to actually hit the log-out button, not just close the browser. Next, stop CSRF from getting to your critical websites by using a separate browser to access them. Companies are increasingly using separate browsers for accessing intranet applications and the internet - more should follow suit.
If your web application is attacked by a CSRF, all you'll see is normal transactions being performed by authenticated and authorised users. There won't be any way to tell that the user didn't actually execute the transaction. Probably the only way you'll find out that you have a CSRF problem is when users start complaining about phantom transactions on their account. The attacker can cover their tracks easily by removing the attack once it has worked.
Taken alone, CSRF attacks are simple and powerful. However, most attackers use CSRF and cross-site scripting (XSS) in conjunction. Together, these two techniques allow attackers to invade a victim's browser and execute malicious programs using the credentials of site the user is logged into.
This combination is devastating, and I'm frankly surprised that a cross-application CSRF-XSS worm hasn't already been developed.
The best solution to CSRF is to require a random token in each business function in your application. You can generate the random token when the user logs in and store it in their session. When you generate links and forms, simply add it to the URL or put it in a hidden form field. For example:
Requests that show up without the right token are forged and you can reject them. If you want to add protection without modifying code, the OWASP CSRFGuard is a filter that sits in front of your application and adds token support.
Whatever steps you take to protect yourself - whether it's the physical act of using different browsers or taking a token-based approach with the OWASP filter, make sure you do something - and soon. It will be difficult to roll out protection against forged requests once an attack has started.
Jeff Williams is the founder and CEO of Aspect Security and the volunteer chair of the Open Web Application Security Project. His latest project is the Enterprise Security API, a free and open set of foundational security building blocks for developers.