For security reasons, Greasemonkey uses XPCNativeWrappers and a sandbox to isolate user scripts from the web page. Under this system, the user script can access and manipulate the page using event listeners, the DOM API, and GM_* functions.
Sometimes the sandbox is too limiting, in which case the user script can access other parts of the page using unsafeWindow. As the name unsafeWindow implies, this can often be unsafe, and expose security holes.
In December 2005, Jesse Ruderman came up with the location hack, to be an alternative to unsafeWindow in many cases.
Basic usage: page functions
Suppose the page contains a function called
The user script knows this function as
The user script could simply call
unsafeWindow.pageFunc(), but this can leak the sandbox.
Instead, the user script can take advantage of
Just entering this URL into the browser's location bar does not leak a GreaseMonkey sandbox:
A user script can programmaticaly navigate to this URL, to safely call the function:
That, in a nutshell, is the location hack! Essentially, it is wrapping a bookmarklet into a user script.
It's important to add the
;void(0) to the end, which keeps the browser from actually navigating to this URL after it is run.
Modifying the page
The location hack can do anything a page script or bookmarklet can do, so it can modify content variables and such as easily as it can access them. For example:
Note: The reason why you use location.replace and not location.href is so that your script does not change the url history and break the back button on the browser.
Executing large blocks of code
Even though the function is defined in the sandbox, it is not a closure of the sandbox scope. It is converted to a string and then back to a function in page scope. It cannot access anything in the sandbox scope, which is a limitation, but is also essential to making this technique secure.
Double Slash Comment issue
As of Firefox 17.0, you can no longer use // (double slash) comments within the location hack. For example,
The above code will cause a syntax error. The workaround is to use /* */ (slash star or multiline) comments instead:
Percent encoding issue
Sometimes percent-encoding the percent symbol is required. For example,
The above code will cause error because %22 is interpreted as double quotation mark. The workaround is:
See also encodeURI().
The location hack is really handy for passing values to the content scope, or to call functions defined there.
It is not, however, capable of directly reading a variable or value returned from a function.
Furthermore, it is run asynchronously, much like
setTimeout(), so you cannot immediately rely on side effects.
(If you use the location hack to, for example, store a value in the DOM and then attempt to read it, it will only be available at some other later point in time.)