Thursday, January 7, 2010

XSS and Ultra Short Urls

I recently was trying to create a POC (proof of concept) for an html injection/XSS vulnerability I found in a website where I could include the tags:
<script src=""></script>

However, I only had 30 characters to break out of the current tag and insert my script. This made me (naturally) search for ways to condense everything into as few characters as possible.

Below is where the html injection occurs:
<input TYPE="TEXT" NAME="target_pattern" VALUE="!INJECTION!" SIZE=20 maxlength=30 ONKEYDOWN="someFunction()">

The full (uncondensed) html I had to include to break out of the current tag and create my script tags was this:
"><script src=""></script>

Which is way more than 30 characters (62 characters). To smash it down, first I looked for different ways to reference a url. I found that

works just as well as including both forward slashes in the url.

Then I tried to find a good url-shortener to create a super-small url that I could use. The smallest I came up with came from, where I managed to get a url similar to The full length I came up with was 37 characters long, still too long for me to actually use to get under the 30 character limit imposed by the server (not the text box):

Since I couldn't think of a way to make it much shorter, I stopped there. Any ideas on how to have a super-short <script></script> block? I came up with one way that would work in specific situations (sadly, not this one though). Instead of trying to include the </script> tag at the end (which is what pushes me over the limit), I figured I could do something like this:

What this would do is comment out everything after my script tag. However, the only situation in which this would still work is if there is a script tag farther down in the html that has a block comment. For example, such a situation would produce something like this:
<input TYPE="TEXT" NAME="target_pattern" VALUE=""><script>/*" SIZE=20
               maxlength=30 ONKEYDOWN="someFunction()">
<!-- farther down -->
<input type="text" value="should be commented out"/>
/* Here is a script block comment */

If such a situation could be found, my injected <script> tag would have a matching script tag farther down the page, which would complete my script block and would load the external script referenced by my shortened url.

Working copy:

Actually, blogspot won't let me publish a working sample of the code above, because there is no matching </script> tag. So, if you want to test it in your browser, you'll have to copy the code and run it on your computer.

Another thought that occurred to me while I was experimenting with url-shorteners is that it would VERY handy to have a url-shortener that passed supplied url params onto the target url. A shortened url, such as that references would then be able to be used like this:, which should end up with the final url of, which, of course, would give you a search for cookie recipes.

This would open up a different way to do XSRF, since most url-shorteners (at least the ones I tried) don't keep the url-params from the target url.

Any comments?

UPDATE: mckt ( suggested using // instead of http:. He explained that the same way a single slash in front of a path means to use the current domain, that a double slash means to use the same protocol, which in this case is http.

This drops the total injection down to 34 characters:
"><script src=//></script>

This also drops the injection code with the javascript comment down to 27 characters:
"><script src=//>/*

Almost down to 30 characters!

UPDATE (1/12/09):
I was brainstorming other ways to go about doing this with Miles, and we came up with something:
"><script />

30 characters! I had tried using <script /> tags (no second closing tag), but had only tried them in Firefox. Miles brought it up again and tried it in Safari, and boom, it worked! It also works in Chrome. I think it's a WebKit behavior that accepts those types of script blocks.

Originally after we had started experimenting with the <script /> form, we were still using // as the url to load our javascript from. For some reason, it just wasn't loading our script when we tried it on the site we were testing. So I used the firebug console and typed location.href = "//", which took us to instead of It soon became very apparent that doesn't support https, which was causing the problem.

To fix the problem, we had to revert back to the slightly-longer form of However, this was still under 30 characters, so we met our goal.

I learned a lesson to not forget what the shortcuts mean when you use them. I could have easily pounded my head against this one for a long time without realizing why it wasn't working. Shortest ≠ bestest (I know, bad grammar, but it rhymes!)

I also posted something over at asking for other ideas. It might be worth it to check back on that every now and then.


  1. Did you know you can shorten your long urls with AdFly and make money from every click on your short urls.

  2. BlueHost is ultimately one of the best web-hosting provider with plans for any hosting needs.