Hmmm… that’s not entirely true. With IE 6.0.2900 and probably earlier versions of Firefox / other browsers it was possible to make the XMLHttpRequest object call any server, which would be great for a Denial of Service (DoS) attack. Imagine you have a site with millions of page views a day? And your’e feeling unfriendly and want to create a DoS attack against your foe. Easy, you put some script in a page which is frequently viewed, and unknowingly, every one of your readers viewing that page makes a call to your foe’s website, stretching its abilities to relpy to all requests, resulting in the DoS attack, which might even take down the server… Or even worse, an unfriendly user of yours posts some content to a forum containing a script to perform that DoS on their own enemy!
Luckily, that security issue was fixed in IE 7 and Firefox 2 (at least the versions I tested on which included service packs). But there is another reason why it is dangerous for an AJAX client to be able to call any server: Scripts have access to cookies and the URL, which means they have access to session IDs. If scripts can send data anywhere, they can easily hijack the session ID and pass it back to a malicious server. As a reminder, a session ID works like this: a user makes a request to view a page on a server. The server checks for a session ID in a cookie or the URL. If its not present, creates a unique ID and sends it back to the user, and probably sends them the login page instead of the original page they wanted to view. Once the user sends their login credentials and the session ID back again, the server checks their credentials and remembers that the user is authenticated and only relies on the session ID being around in every call which the user makes. So anyway, a script can send the cookies and URL to a malicious server which in turn can make its own request to the original server, pretending to be that user. Such an attack is known as a cross site scripting (XSS) attack. Theoretically, the malicious server could change the password, transfer funds to its own account, make forum postings on the users behalf, etc. Whether the connection between the user and the original server is secured over SSL is irrelevant because the script is running inside the users browser.
But how does a malicious script get put on a site in the first place? Its not like the author of a site would go to those lengths, since his server has the session ID anyway, and the user is one of his customers! Well luckily, this is the hard part, and as a systems designer, you can still protect yourself against such attacks. Lets say someone has the intent to create such an attack. They need to somehow get the script into a page which other people can view. To do that, they would look for a forum or page where they can make a posting. So most corporations like banks or online shops are already protected because they don’t allow such posting, although it has become trendy for customers to be able to post reviews, like on Amazon.com.
I then logged in as a different user on a different browser and read the bogus posting. Indeed, the applet posted the session info back to my server. A few milliseconds after "the user" had read the provocative thread, I had their session ID. Whats more, I’d already programmed the malicious server to make a posting on behalf of the different user, telling the world that the site had been hacked 🙂
I nice little experiment I thought, but let me repeat, this was all done on my own servers, in fact locally on my laptop – no ones accounts are in danger! The point is, that its VERY easy to steal session IDs, if there is a way to make a posting that contains script. So by default, my bank is NOT open to such an attack, which makes me happier about using their online services. Even if it were, they have gone to the extent of requiring me to retype parts of my password if I want to transfer funds to a different account, although as I’m writing this I don’t think that’t the case when I pay bills…
By far the best protection against such XSS attacks is to strip out any script and simply not allow it to be posted. Lots of big sites do that (e.g. Mediawiki doesn’t even let you post HTML, they have their own format). I have read that Google even has their own parsers for stripping malicious code out of postings, which shows how important they think it is to protect the world against such attacks.
Other forms of protection I have seen as to put all postings inside an "IFrame" – a special HTML tag which loads content from a site inside a frame protecting the rest of the page from that content. In my tests, code running inside an IFrame still had access to some of the cookies from the main outer page, so if a session ID is contained in cookies, its still not safe. It was interesting to note that Firefox 2 provided some of the cookies while IE 6 didn’t provide any.
The final way to protect your sites users is to get them to provide parts of their password again, when they are doing anything important, like making payments or postings. That way, a malicious script has no chance of spoofing their actions.
Copyright (c) 2008 Ant Kutschera