Monday, 14 June 2010

The Problem with XSS

Dear Junior
I guess that one of the first things you have to do to address security risks like Cross-Site Scripting (XSS) is to learn what they are about. Here I must admin that even though I have been interested in security, I have lived in ignorance about several of the most common attack techniques. OK, I had some vague idea what a XSS attack was like, but would not be able to explain it. Really I have to thank my colleagues Michael Boman and John Wilander for finally setting the details for me.
Deep down XSS is really about making someone run a program that they did not intended to run. That program might be a harmless pop-up You have been XSS, it might be a local port-scan, or it might be installing a keylogger.
The road to make this happen is to mix up the distinction between code and data. This is typically in a web browser which is fooled to accept something that looks like content (data), but actually is JavaScript (code) that gets executed in the browser.
There are several ways to make a XSS happen but the one I have found most easy to understand is what is known as the stored attack.
Imagine that you have a community site with some discussion forum on say how to raise children. Member parents can enter posts and comments to a discussion. When you go to the discussion page, all posts and comments are sent to you as an HTML page and rendered onto your screen by your browser.
Let us imagine what happens if some evil pretend-to-be-parent enters a comment saying I think you should <script>alert(Spank them!)</script>be nice to kids; what would happen? When you, the unsuspecting victim, browse the discussion you get back an HTML page. To start with, the page you get back is valid HTML it is allowed to drop in a javascript almost wherever you want to. Your browser will render the text I think you should be nice to kids, and the script will be executed popping up an alert saying Spank them!. Of course, a yet more evil pretend-to-be-parent would substitute alert for less pleasant, and now the computers of all unsuspecting parents are infected with keyloggers stealing their credit card numbers and uploading them to some obscure server in unknown jurisdiction.
This variant is called stored because the attacking script is stored on the forum server. There are other variants for getting the javascript into the poor browser, but I have found this the easiest to understand.
So, what is the problem? A simple way out is to blame it on bad indata validation. The forum comment I think you should <script>alert(Spank them!)</script>be nice to kids should simply not have been accepted and in this case that might be true. If it had been a discussion on JavaScripts, it might have been a little trickier.
Another way to view the problem is that the browser has mixed up data and code. What was data (the forum comment) was interpreted as code and executed. No good. But that would be a case of blame-shifting, because we (the programmers developing the forum site) are perfectly aware about how browsers work.
So really, the problem is in the forum application that mixes up domains. It takes what is a comment in the in-data domain (text field and http request), and happily let it go over to the presentation domain in which it is interpreted not as content, but as code. How come? Well if we want the string <script>alert(Spank them!)</script> to be interpreted as content in a browser we must encode it properly. So, the long-and-winding answer is that we have missed to apply the proper encoding when transforming from the comment domain to the html-presentation domain.
Now, here we have formulated XSS as a problem in Domain Driven Design terminology then we can see what Domain Driven Design would do to address the problem.
But that must be the subject of another letter