Home
Site Feed
 

Mitigating Cross Site Scripting

In my last couple of posts I've talked a lot about Cross Site Scripting (XSS) prevention. I wont repeat myself and tell you why XSS is bad and a very real problem, but I do want to say why I choose to write this article. First of all I would like to write down my thoughts and knowledge of XSS for myself and the rest of the world for later use. But besides the usual (very well documented) prevention of XSS this article also covers the things you can do in order to prevent an attacker from exploiting your website after he found a XSS vulnerability! This is a far less covered topic and something everyone should think about (and implement if possible). I am NOT saying you should rely on these methods, but the certainly do provide a onion layered security around you website where a single flaw might not be an open door.

As most of my posts this will be written incrementally, and I may add additional points in the future. Since I know this could be quit long I am just going to go directly to the point and sort the list after importance (personal opinion) and efficiency - weighted a bit by the practicality.

Sanitize Everything

Okay, this is the obvious one, and the way it's primarily done today. When users post any kind of input on your page you need to sanitize it, escape the hell out of it, and make sure he does not have any chance what so ever of injection any kind of scripting.

Again it is worth pointing out that home brew parsing is the best way to make sure that your site has more holes than a Swiss cheese.

Authenticate the transaction, not the user.

It is remarkable that this has not received greater adoption yet - not even all banks do it(!), and it is worth a post of it is own. If a simple thief steals your wallet they will most likely take your money and leave your credit cards, because credit cards require you to authenticate every single transaction (with a PIN). If every single sensitive action on your page requires authentication there is little XSS can do. Many pages requires you to enter your old password before changing to a new one - this is good but does not go far enough. I would like my gmail to authenticate me every time I changed my settings, created new filters etc. This does not have to be a inconvenient as typing my 20 character long password, but just a 4 digit PIN code would significantly increases the security - assuming you keep an eye up for brute force attacks of course. What kind of authentication you need depends on the condition. Sometimes a long password is required, sometimes a short PIN will work, and sometimes you need a CAPTCHA.

Keep in mind - in this scenario of a web page an attacker with the ability to perform XSS can essentially perform a Man In The Middle (MITM) attack on you, intercept your PIN. However, even a PIN still offers a great amount of security since the XSS vulnerability has to be on the same page as the user is submitting the form in order to do so. That is, say there is a XSS vulnerability on a community sites profile page, the attacker may be able to perform AJAX calls and try to send messages to other users or post on the local forum but wont be able to because he does not know the PIN, and when the user is posting the profile page wont be loaded - making the attacker is unable to intercept the PIN. However, in any case a CAPTCHA or other quick, and not to annoying, one time authentication is a better choice since it prevents replay attacks.

At last, there is still the possibility that an attacker could inject JavaScript on a critical page and wait for the user to submit the desired form. In this case it would still be possible to do a MITM attack and just substitute the users input with your own. This can somewhat be mitigated by notifying the user of what he/she just did - preferable trough a second channel like E-mail - and giving them the option to undo it.

Serve user generated content from a different domain

Another very general, and very effective defense is to serve all user generated data from a different domain. This prevents the attacker from accessing any kind of information - what so ever. The main problem however is that it is difficult to implement. Since I soon will allow everyone to edit my posts on this page I plan to implement this on my page as well. The main domain for this page is Bottiger.org, but since all posts will be editable by random visitors all posts will be included in an iframe from Bottiger.net, and so will comments. This wont allow an attacker to access anything on the .ORG domain.

But if everything is just included from .NET, why would you want to have access to the .ORG domain, and not just use your escalated XSS abilities to steel the cookie from .NET domain, and still gaining full access? All the authentication should be done at Bottiger.org, and when a user is authenticated, and need to request some content from Bottiger.NET the server will generate a one-time subdomain (e.g nbkn1k4bBh.bottiger.net) and include that in an iframe.

This is of course not practical in every case, but when it is - it should work damn good. Even if the user injects malicious JavaScript on a page, then page will be included from a different domain and thereby not having access to anything besides the content on the page it lives on. And since it is even included from a (random) subdomain it wont know where to find any other content on the .NET domain, and even if it did JavaScript can not access content on a different subdomain.

The biggest problem I see is from a Search Engine Optimization (SEO) point of view where it could cause some trouble, but I will implement it and see how it works.

Content Security Policy

Content Security Policy is a new emerging standard from W3C which has been implemented in Mozillas Firefox 4, and is soon to be found in Chrome as well (and other browsers will follow soon I expect). It allows the webmaster to tell the users browser what it can and what it cant do. An obvious appliance would be to only white list inclusion of your must have JavaScripts like Google Analytics and you own personal inclusions and black list everything else - including javascript directly on the page itself. I wont go into great details here since I have already written a lengthy post about it - but if you do not know what it is I highly recommend that you read up on it.

HttpOnly cookies

Yes - I have also talked about these before, but since this a write up of all the defensive techniques I know of I will mention them again. HTTPOnly cookies is not a bulletproof defense, but they prevent the attacker from reading cookies using JavaScript and thereby provide decent protection against steeling your users sessions. However, you should know their weaknesses too, and I can only recommend you read my previous article.

Remove the motive

While this inherently is not possible for most pages, it is the best protection you can possibly get. People only commit crimes (or XSS) because they have a motive - remove the motive and you remove the threat because if people do not want to do it I can assure you they wont. For instance, other than proving a point (which admittedly can be a quite strong motive for some) there is little reason to attack this site. There are not user sessions to steal and since everyone (soon) can edit anything by default there will be -is- no privileges to gain. There is simply no benefits to gain from XSS which should make it pointless to do. I choose to put this far down the list because while it is very efficient, it rarely enforceable.

Bind your cookies to an IP and sign them

Again, the most common user of XSS is when the attacker includes some JavaScript on a webpage and thereby gains access to the users sessions and steels them in order to hijack the users session and log in as the user. In most cases the attacker will not be on the same LAN as the user, and thus have a different IP address. If you include the users IP address as a part of the cookie this should prevent an attacker from hijacking his session. This of course assumes you sign the cookie in order to prevent the attacker from just modifying it and validates the cookie signature.

Irony Strikes Again

After making this article public this happend. To bad I had not implemented all the thing I talk about myself (yet)

By if you liked it, hit the +1 like a man! 

Tags: security, xss, mitigatin, javascript

Post a Comment

Showing 4 comments

By Darren on 28/06/2011 at 09:15PM

Unfortunately we are in the same boat as you. The "proving a point" motive always seems to be a popular one whenever an article of ours makes it to FD or reddit.

By Bob Smith on 27/06/2011 at 06:39PM

This is a test comment. It is not spam.

By test on 27/06/2011 at 06:36PM

sadsdas

By test'"><s>asd on 27/06/2011 at 06:35PM

</textarea><s>foobar