[Greasemonkey] Greasemonkey 0.4.1 (The Next Generation)

Aaron Boodman zboogs at gmail.com
Tue Jul 26 12:50:13 EDT 2005


It's been a lot of work to get Greasemonkey secure and compatible with
both older scripts and older Firefoxen. I've learned a lot.

A few of us have been going around and around for serveral days now --
each time I thought I had the right approach, and then it wouldn't
work for some random script. But I think it's finally to the point
where it would benefit from more eyeballs. In any case, I'm getting
impatient and I'm sure you all are too.

If you are daring, please back up your scripts directory and try out
this new Greasemonkey and let me know what works and what doesn't.


It appears that Deer Park's extension manager is a little bit better
about cleaning up uninstalled extensions. If you install a new
Greasemonkey, it will delete all your old scripts. Make sure you back
them up.



All APIs have been restored (and a new one - GM_openInTab - has been added).

The |document| and |window| global variables are special in Greasemonkey now. 

In Deer Park, they are XPCNativeWrappers
(http://developer.mozilla.org/en/docs/XPCNativeWrapper). If you want
the other window -- the one that content refers to as "window" -- you
want the |unsafeWindow| global variable. You should not use
|unsafeWindow| unless you need to call a function which is defined by
content, for instance, like bloglinesautoloader.user.js does

For compatibility, just contentFunction() will still work, but it is
recommended that you use unsafeWindow.contentFunction() instead.



Greasemonkey TNG should be backward compatible with all your existing
scripts in FF 1.0.x. Please let me know if it is not. For Deer Park,
you will have some difficulties because |document| and |window| global
variables are XPCNativeWrappers in Deer Park. See
for more details on how to avoid these pitfalls. I hope to write an
improvement of XPCNativeWrapper for all Firefoxen which will not have
these limitations, but it doesn't exist yet.


Content stealing APIs

It should not be possible for content to snarf references to APIs
*generically*. By "generically", I mean, in every single user script
regardless of implementation.

It *is* possible for a user script to explicitly pass a GM* api to
content, which would be a bad thing. For instance, if you had a
reference to the content window and you did this:

contentWindow.GMfoo = GM_xmlhttpRequest

you just gave content access to GM_xmlhttpRequest. Don't do that!

You can also accidentally pass GM_* to content by passing it as an
argument to a function. For instance, if you did this:

function foo(gmx) {


then someContentFunction could look up it's call stack and steal the
reference to GM_xmlhttpRequest. You shouldn't do this either.

As a basic rule of thumb, do not copy GM* APIs anywhere and do not
pass them as arguments. This will keep you out of trouble.


Method Redefinition/Untrusted Functions

There are a whole class of security issues surrounding Greasemonkey or
user scripts calling functions in content that it can't trust.

This happens two ways: method redefinition and calling content functions.

Method redefinition is when your user script calls - for instance -
document.getElementById, but content has redefined
document.getElementById to do something else. Like:

* look up the call stack to get the source code of your user script
* get references to GM APIs that you have incorrectly passed as arguments
* block your user script from running by doing nothing or throwing an error

Deer Park deals a major blow to method redefinition with the
introduction of XPCNativeWrappers. The |document| and |window| global
variables are XPCNativeWrappers for Greasemonkey user scripts, which
means that their methods, and the methods of any XPCom objects they
return are safe to call and cannot be redefined. The entire DOM is
XPCOM objects, so it is pretty safe.

However, there are some non-XPCOM objects in Javascript like Math and
Array; as well as the objects that user scripts and content define. 
These objects are still vulnerable to redefinition, even in Deer Park.

The boiled down result of all this is that:

* There is no generic way to block or detect Greasemonkey TNG itself

* There is no generic way to block or detect user scripts in
Greasemonkey TNG *** running on Deer Park ***

* In FF 1.0.x, it is pretty easy to detect/block most user scripts by
redefining core DOM methods like document.getElementById and

* Even in Deer Park, it is *possible* to detect/block individual user
scripts by looking at the content-defined functions they call or the
intrinsic JavaScript objects they use.

* You should not consider the source code of your user scripts secret.
If content wants to get them, they can. Do not put passwords in your
user scripts if you don't want content getting them.


Best practices

* Read about the limitations of XPCNativeWrappers:

* When accessing the DOM, start with the |document| or |window| global
variables. For instance window.alert instead of just alert.

* Test/develop in Deer Park if at all possible.

* If you need to access the content window to call a function it
defines, or to look at variables it defines, use the unsafeWindow
global variable.


If you made it this far....

You are a madman (or woman). Congrats! I have some ideas to fix
XPCNativeWrapper to work with all objects, but it will have to wait. I
need to get back to work.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: greasemonkey.xpi
Type: application/x-xpinstall
Size: 54160 bytes
Desc: not available
Url : http://mozdev.org/pipermail/greasemonkey/attachments/20050726/3196b128/greasemonkey-0001.bin

More information about the Greasemonkey mailing list