Understanding the Greasemonkey vulnerability
If you have any version of Greasemonkey installed prior to 0.3.5, which was released a few hours ago, or if you are running any of the 0.4 alphas, you need to go and upgrade right now. All versions of Greasemonkey aside from 0.3.5 contain a nasty security hole, which could enable malicious web sites to read any file from your hard drive without you knowing.
Unfortunately, 0.3.5 disables all of the GM_ API functions, without which many of the more interesting user scripts out there simple won’t work. This is a temporary measure—the
GM_ functions should return in a later release, once the security problem with them has been resolved.
XMLHttpRequest—you are only allowed to make an
XMLHttpRequest call back to the domain from which the script was originally loaded.
This policy exists to prevent cross-domain attacks. Say for example you work for a company with an intranet hidden behind the firewall, full of interesting proprietary information. Without the same-origin policy, malicious sites that you visit on the public internet would be able to read information from your intranet, using your browser as the middle-man.
GM_xmlhttpRequest API function does not have this restriction—it can load data from any domain. This enables a whole host of interesting user scripts—the most famous of which is probably Book Burro, which shows comparison prices from different online stores for the item you are currently looking at on Amazon, Barnes and Noble and more.
Malicious user scripts could use this feature to steal information from your private intranet, but malicious user scripts could also do all manner of other nasty things—stealing your Hotmail password for example. This is why you should never install a user script from an untrusted source without first reviewing the code.
Restricting API functions to user scripts only
To keep things safe then, it is essential that the
GM_ family of API functions can only ever be used by user scripts, not by code running on pages that you have visited. By installing a user script you have declared it trustworthy—but visiting a web page does not carry that contract.
The way the flawed versions of Greasemonkey do that now is simple: the
<script> elements, they run, then the
GM_ functions are removed from the global object to prevent scripts on the page from accessing them. This works because Greasemonkey injection and execution happens just before the onload event is fired—which is when most well behaved scripts kick in.
The file:// protocol
Here’s the final piece of the puzzle: the
file:// protocol in Firefox allows you to view files and directory listings in your browser. Unfortunately, it also allows the
GM_xmlhttpRequest function to do the same. It’s not at all hard for a malicious script to use the function to load in files at a known location—or even load in directory listings (as HTML), parse them and use them to find all kinds of things scattered around your hard drive.
Solving the problem
The principle problem then is the requirement for “safe” Greasemonkey API functions—that is, functions that can be used by the user scripts but not by code running on a website. Aaron is looking in to this right now—it looks like the solution will require a minor change to be made to many existing scripts, but the trade-off in terms of security is more than worth it. The
GM_xmlhttpRequest function will also be modified to disallow
Until then, 0.3.5 is the only safe version of Greasemonkey.