When I started this research I had no idea what I was looking for I just did it for the thrill of discovery or fun. After a while I thought I could perhaps learn something by classifying the vulnerabilities. I used “view source” to see exactly why the XSS was triggered and then I added a tag to the bookmark in my delicious stream. (No need to look for live vulnerabilities in my stream they are all private until disclosure). Each time I bookmark a vulnerability I get an update on the popularity of the causes. And that picture is the subject of todays post.
The most common cause is to echo back an untreated input parameter. A great many web sites out there provides a search box to assist users finding what they are looking for. A very basic FORM could look like:
<form action="/search"> <input type="text" name="query" value="Type query here"> <input type="submit" value="Search"> </form>
This is typically implemented like:
<form action="/search"> <input type="text" name="query" value="<?php echo $_GET['query'];?>" /> <input type="submit" value="Search" /> </form>
Search for this “><script>alert(’00ps’)</script> and the resulting HTML is:
... <input type="text" name="query" value="
"><script>>alert('00ps')</script> /> ...
The browser will happily interpret that script block. Newer browsers (Safari, IE8-) will detect this situation and avoid execution of “user” injected script. Not all browsers has this yet and it’s from all users who has up-to-date with browser versions. Web site owners can run form the responsibility of making their web site safe. The correct solution in the above case is to sanitize input data. Keeping Web Users Safe By Sanitizing Input Data has a good description of input filtering.
Here is a very very clean example from of all places NATO. I have contacted them twice and explicitly said I would disclose the issue. So far all I have managed to get is an automatic response.
Let’s try in Danish:
Kære Anders, Jeg synes det er pinligt at NATO’s hjemmeside har et så banalt sikkerhedshul. Det er stærkt bekymrende det ikke er blevet fikset her en uge senere. Jeg fristes til at tro der mangler en sikkerhedspolitik for nato.int. Mvh. Peter. PS: Jeg vil ikke sige nej tak hvis jeg fik tilbuddet om at hjælpe med at forbedre nato.int’s internet sikkerhed .
A very large number of web sites actually does a good job of sanitizing the data. And yet a lot of them are still vulnerable. It surprised me at first but I think I have found a plausible explanation. After the site is done and all functionality is working fine it’s decided to add either ads or analytics section. The is frequently done with Google Analytics or Omniture. What happens is that the site owner probably gets some boilerplate code:
They blindly trusts the code and inserts it in their web site. lonelyplanet.com had that exact problem. They fixed it in a matter of days. When such a big site can fix a problem so quickly then everybody else can. G’day mates, thanks very much for the guide book I got in return, really appreciate it
Omniture tracking also comes with some boilerplate code (I’ve removed some blank lines):
The observant ready already noticed I found this on LA Times. LA Times have not responded.
Search for “;alert(’00ps’);” and get
var searchWord = "";alert(/00ps/);"";
Seen om Fødevareministeriet. fvm.dk has not responded.
This is the absolute easiest way to get into trouble. In PHP you can do that with just a single line:
You typed <?php echo $_GET['input'];?>"
The vector would be http://servername.domain/?input=<script>alert(’00ps’)</script>. facebook had one of those just a couple of days ago. Testament to this problem can slip into production for anybody. Here is a live example from Denmarks largest political party. Please remind me to ask them about security policy
This is a fun one because scripts-tags are not valid inside title-tags. Sure enough script-tags doesn’t work. A lot of sites then falsely makes the assumption that filtering is not needed. But they forget that it’s possible to an end to title context with something like:
Among the sites with that type of flaw we find acm.org. They were notified in early October 2010.
Dear developers, do not ever allow untreated user data to be echoed back to the client.
Putting debug output inside HTML can not harm, it’s just a comment, right? Wrong! It’s stops being comment context if part of the debug output is –>. A string like:
will demonstrate such a vulnerability.
There are many reasons why debug messages on your life production site is a bad practice. Security, performance, privacy are just some. I also think it’s a sign of sloppiness.
This is a special case of untreated_attribute_context. Nothing really to say about this that hasn’t already been in the above.
These are just so much fun. Basically the error message is taking from parameters in the URL. Any use can change the wording of the error message. I have just recently found a couple so we have to wait a bit with the disclosure. An example has been described in great detail by bluesmoon.
If there is an error the error code should be carried around in a URL parameter, never ever the actual error message. When the error message is needed it can be looked up with the error code as index.
A standard technique for creating a sandbox for 3rd party content like ads, is to include it inside an iframe. Once inside the iframe the Same Origin Policy ensures potentially bad code can’t reach into the surrounding page. This probably leads programmers to think anything iframe is safe. Proceed with caution. Let’s looks at an example where search results are contained inside an iframe.
<iframe src="search?query=" frameborder="0" width="500" height="400" scrolling="auto" name="int"></iframe>
The search box is in the surrounding page. When submit is clicked a request is sent to the server which then generates a new surrounding page where the above iframe embedded Let’s say the query is:
"></iframe><script>alert('00ps')</script><iframe src="search?q="></iframe><script>alert('00ps')</script>" frameborder="0" width="551" height="405" scrolling="auto" name="int"></iframe>
The iframe is closed and a script section is injected in the surrounding page. I repeat myself, but it’s important to always sanitize all input data, no matter where in the page you intend to put the data.
Do not ever echo untreated input data back to the client As seen from the above it’s doesn’t matter where the data is going. And it doesn’t matter who you are, we should all make sure to sanitize all input data. It is so important that I am still surprised it is done by default in web frameworks. In a future post I go into some detail about how to sanitize data.
Todays letter is j
Found 11 j’s in the domain names of vulnerable sites. One of those is the big Danish company Jysk. It was a plain echo of the untreated query into the HTML. A very common vulnerability as we will see today. Jysk fixed the problem in a matter of days and they send me a number of movie tickets. THANKS.
Todays domain is ca
Found a vulnerability on a single .ca site. Once the disclosure date is reached I will cover it in more detail. It will be good fun. Hi Canada, Hans Island is Danish.
Todays disclosed vulnerabilities
Warning active XSS ahead, click at your own risk (or for your own amusement).
- Day 4 and the first success
- Day 6: Why can’t you fix an XSS in less than a week?