URLs, AJAX and Script Injection


The paradigm of a URL being a Uniform Resource Locater seems to no longer hold true. Examples of this include personalized search results returned by Google, and more importantly AJAX. It gets irritating when you send across a link, expecting people to see the same web page as you did, but the result is a complete shock. Page personalization seems fair, and there are ways out of it, but the way AJAX prevents information from being shared using a URL is definitely a concern. With social bookmarking and site sharing on the rise, any website that denies the convince of URL sharing is sure on a back seat.
The main problem that AJAX has with manipulating URLs to represent correct information, or page state is that if it directly rewrites document.location or window.url, the page is caused to refresh, defeating the purpose of AJAX. Developers are smart, and thats where they started to exploit the underused feature of page anchors. Most web browsers do not refresh a page if all that changes in the URL occurs after "#". Hence, it is now a recommended practice to save the state of the page as an anchor. Most pages typically look like "http://page.com?params#state=1".
Another advantage of this approach is that it does not upset the behavior of the "BACK" navigation, another pain point that was a result of transitioning from web pages to the web applications paradigm.
This hack also opens up a wide list of security vulnerabilities. May be I could make myself clear with an example.
There was this session at the Barcamp that I attended yesterday on mashups, mapping and the promising Yahoo India Maps. Yahoo maps is still in beta, but the fact that impressed me was it attracted a lot of local janta wanting to mash up. The session by Shivku that revealed the extensive use of JavaScript got me probing.
Yahoo India Maps is a classy example of URL rewriting using the # function. Hence, I can plainly send something like this to indicate a location in Bangalore. http://in.maps.yahoo.com/#?lat=12.922420&lon=77.593195&z=1&addr=jayanagar%2C%20bangalore
The advantage of this over Google Maps is that I just copied this from the address bar. The security problems in this case may also be evident. People would become wary of links that say something like javascript:(alert(''))();, but a url like the one for Yahoo India Maps is something that people are fine with. Now, if we are able to get some SQL injection done on a URL like that, given the fact that the URL is actually parsed at the client side, it makes an excellent case for Script and HTML injections. I know that this is nothing new, and people have been doing injections like this for ages, I just wanted to list down my experience of finding such a hack.
Let me put down the results of my analysis. Though the Yahoo Maps code is compressed, we can quickly figure out that in the global namespace, the function "getParams(arg)" does the actual parsing of the URL. A second search on getParams gives us all the places where getParams is actually used. Closer inspection reveals that the possible parameters [i.e. loc, lat, pg, ms, mt, lc] directly correspond to the URL parameters .This is to be the source of our injection.
Now looking at the place where we should inject, a quick search looking for all places where the parameters [i..e DEFAULT_LAT, DEFAULT_LON, etc] are used. Unfortunately for us, the there is no place where the latitude or longitude is used. Interestingly however, there was a place where the location was used. It turns out to be written to a text field, and we have hit another dead end. I ran a couple of tracer scripts to see if I could see any other injection targets, and I realize even the category text is a number; the real text comes from a back end call.
After some searching, I finally stumbled upon the print link, and saw that in the print page, the 'addr' argument was 'unescaped' and written. Now, all I had to do was to check that function out, get the escape value of "<" (so that unescaping inserts the character). A few minutes later, I cooked up the following link.

Well, now the question of potential exploits. Consider the case where a user is logged into YAHOO account. Yahoo Maps obviously has his cookies, and if I insert a script to include a malicious js (instead of the current alert hello world) i could cleanly steal cookies. Technically, that would let me log in as any user, and propagate it to friends, and friends of friends.
Thought I have not really tried, and hope that it does not work, I could use a service like YAHOO answers to post the cookie (like the cookie jars available on orkut) as a reply to a question. That would still keep me undetected, and I am not really posting data to a server.

To summarize, the idea of sanitizing the URL paradigm is great, but I believe that the Javascript developers must be aware of the potential problems that it may bring in.