With the hype around AJAX many people jumped on the Javascript bandwagon and assumed that everything should be done client side (even encryption) and even when perfectly suitable server side solutions exists, people insist on using Javascript. (Just a quick note: I realize that many times a well written client side script can (a) hide the network latency and (b) reduce the server load, however it is recommended that you use progressive enhancement to ensure that your site is accessible by as many people as possible using different devices / technologies).
The newest craze is widgets. Most of the time they advertise their services like just put this one line in your web page and you can X
where that one line is usually a script tag. Their advertisement is entirely correct: they can do X to your page (whatever X may be), but they can do many more:
- Steal cookies from your visitors (including session id)
- Execute a session fixation attack
- Execute a phising attack
- Execute actions on their behalf
- Steal passwords (with a technique recently discovered)
- And generally act as part of your website
The most dangerous thing is to include a third party script in pages which will be viewed by authenticated user (think forums, discussion boards). Also, keep in mind that this can be done either by the site owner or by a third party user (as part of a signature or profile information for example). Admittedly the later is less likely because most of the forum software guard against this, but the the former is former is very, very frequent. Do you use Google Analytics / Sitemeter? Do you add Digg / Reddit buttons to your site? Then you have included third party javascript in your site. (Just to clarify: I do not say that any of the examples mentioned in this post have malicious intent, I just use them to demonstrate how widespread the phenomenon of including third party javascript is)
An other thing to keep in mind that these attacks can be very targeted which makes their discovery and analysis more difficult. The site serving up the javascript may choose to serve up a malicious version only to certain pages (based on the referrer information), only to certain IP ranges or only at random intervals. The fact that you, the site owner, looked through the script when including it doesn't guarantee anything.
I have put together a little demonstration to show the interested a glimpse of the information an attacker may gather this way. Install the following bookmarklet IKWYDLP (by dragging it to your bookmarks toolbar if you are using Firefox or right clicking on it and selecting Add to favorites if you're using Internet explorer - you may need to accept a security warning). Then navigate to any site and click on the button. It will include a javascript hosted on my Google Pages account in the page either directly or with an IFRAME (more on this soon). The nicely formatted version of the source code can be seen below:
Go to some pages and click the bookmarklet to see what an attacker could find out about you. No information is relayed back to me and because Google Pages does not support server side scripting, you can be assured that every time the same javascript is served up. Also, this javascript does basic information gathering for demonstration purposes and doesn't include the advanced techniques described earlier.
Possible protection
How can you protect yourself? First lets take the case of a site owner, because s/he can take the biggest preventory step: include your third party script in a web page, host that web page on a third party service (a very good one IMHO is Google Pages because it has a very good uptime and it doesn't force you to include extra content (like ads) and then include it in your page using an IFRAME. This works because browsers treat domains as security boundaries. Because the content of the IFRAME is hosted on a different domain, it can't interact with the rest of the page. Also, because of this it isn't good enough to create a HTML page on your site, put the script in it and then include it using an IFRAME, because they will still be in the same security zone (from the browsers point of view) and the javascript code can crawl out
and access other documents from the same domain. A last note: there are scripts which from a technical point of view absolutely require to be embedded directly on the page. One of them is the Google Analytics script. If you would to use the IFRAME approach presented earlier, it will basically tell that every visitor you had visited a single page. I would also make referrer information useless. In these cases you have to make a decision about the trustfulness of the company. An other interesting example is Widgetbox. In their case you have to include the javascript code directly if you wish to use some of the extra features, however they make sure that each widget is put in an IFRAME for you (so that you only have to trust them, not each individual widget publisher). Good to see that they think about security.
What can you do if you are the publisher of widgets? The easiest migration path is to place them in a IFRAME and give your users the code to include the IFRAME instead of a script file. You will loose some possibilities (like to manipulate the elements directly on the page), however 95% of the things out there don't need that. The more problematic thing is that you loose the ability to automatically resize your content. This can be partially mitigated by giving the user the ability to customize the generated IFRAME code by specifying width and height. Then again this raises problems with the zoom features present in the browsers. An alternative way (practiced partially by Feedburner for example) is to give you the code which serves up images. They can even be animated (if you use GIFs). It is a little harder to migrate to this solution, but it has the benefit or a larger potential audience (because while most forums disallow HTML or scripting in the signature, they do allow for images).
Finally, if you are a simple user, you can use the NoScript extension if you're using Firefox or disable scripting for your Internet zone and add sites you trust manually in the trusted zone if you are using Internet Explorer. Neither solution is perfect, although the NoScript extension is definitely easier to use than zones in Internet Explorer, it's not alway clear what domains you should enable to get the site functional. Also it seems to slow down the browser.
In conclusion: know the risk of including third party javascript on your site. I do have such javascript (from Google Analytics, some from my Google Page account because I don't want to fill my templates with Javascript and from Digg), but I have weight the benefits and the risks and decided that it's worth it. You should do the same.