[Greasemonkey] A whole other kind of monkey

Aaron Boodman zboogs at gmail.com
Wed Jul 20 11:32:54 EDT 2005

Here is a first cut at what I'm thinking of for 0.4.1. It uses
evalInSandbox at it's heart and has only a few global objects:

* window - a deep XPCNativeWrapper
for the content window. Setting expando properties on this, for
instance, will not be visible from content. Content will not be able
to trick user scripts by changing methods on this object. If you need
to access window, use this object.

* document - a deep XPCNativeWrapper for the content document. If you
need to access document, use this object.

* unsafeWindow - The window that javascript on the content page sees.
You shouldn't need this very frequently, but in some cases it will be
necessary. for instance when you need to call javascript defined on
the target page. This property is called "unsafe" for a reason. The
functions defined in it might be changed by content to trick you. You
might call unsafeWindow.document.getElementById( ) and get an alert
box. The point is that it's impossible to say, so you should avoid
using it where possible.

* XPathResult - convenience because otherwise we'd have to use
Components.interfaces.nsIXpathResult or the actual numbers (0,1,2,etc)

* All the regular JavaScript intrinsics like Math, Date, etc.

Pros of using evalInSandbox:

* No way for content to get access to user script source unless a
script author explicitly does something idiotic (eg -
unsafeWindow.myPassword = "'xyz") -- I can't help with that. Don't do

* No way for content to get access to APIs (again, unless users pass
them to unsafeWindow - don't do that)

* No easy, universal way for content to detect the presence of GM.
Since GM scripts live in their own context, none of the variables we
create show up for content. There will still be one-off ways for
individual sites to detect individual scripts, depending on what
modifications that script makes to the shape of the DOM.

* Not easy for user script authors to get fooled into calling
content's javascript methods because window and document are deep XPC


* Will not work in pre-FF 1.1 alphas.

* Not really possible to make secure *and* fast with existing (as of
yesterday) code. But, Brendan has checked in a fix on the tree that
makes it fast (http://bonsai.mozilla.org/cvslog.cgi?file=mozilla/js/src/xpconnect/src/xpccomponents.cpp).
So as of today (possibly tommorrow, I'll look it up in a second) it
should be much faster.

* Crappy error reporting. Again, Brendan has fixed this, so we should
have nice error reporting tomorrow.


So, a lot of downsides. Why have I done this? Because, as near as I
can tell, there is no way to solve all the potential security issues
we want to solve using any other technique (except for of course
hosting the JavaScript engine in C++ directly, but I don't really have
time for that, and there's not a ton of obvious benefits to doing it
over what we have here).

I could go on and on (in fact I did, but deleted it) about all the ins
and outs of security I've been going through trying to get pre 1.1 FF
to work. But let's leave that for another message and get to ...


What's next?

I have heard that some people are interested in helping to test this.
Let's get started. I'd like some people (Jessee?) to try their hardest

* Get access to APIs from content
* Use APIs from user scripts to do things you shouldn't be able to
(set other people's prefs, read files)
* Do things in general from user scripts you shouldn't be able to
(read files, start processes)
* Get the source code of user scripts from content
* Detect the presence of Greasemonkey or scripts from content
* Block Greasemonkey from content

We shouldn't be able to do any of these things.

Some other people should just try testing all their existing scripts
and see where they falls down. We are using brand new parts of Mozilla
that haven't really been exercised before, so there will be issues.

Keep in mind that *on purpose* the only global objects are window,
document, XPathResult, and unsafeWindow. So you will have to say, for
instance, window.alert("hi!"), not just alert("hi!"). Most scripts
will have several of these types of errors right off the bat.

Also, window and document are deep XPCNativeWrappers and these have
some issues of their own. See here:
for details on those. In all cases there is a simple workaround. You
shouldn't have to resort to using unsafeWindow unless you need to
access JavaScript on the content page.

Also keep in mind that I've really only run this on DPa2 (Deer Park
Alpha 2), so you should start there. After I send this mail, I will
check the latest nightlies. I won't be surprised if it falls down

Here are the issues I already know about:

* Error reporting is a bitch, like I said above. The easiest way I
have found is to wrap your entire script in try/catch and alert your
own errors. See my test user script (attached) for more on this.

* For some crazy reason XPath does not work when it is called from a
function, which itself is nested inside another function. This is
madness. Many scripts have this pattern because they had the anonymous
function wrapper, then another helper function to evaluate xpaths. The
anonymous function wrappers are not necessary anymore!

* It's slow. I know. This should be fixed in latest nightlies.


Phew! This has been enlightening. Can't wait to get your feedback and
get this going.

Oh, and also, I fixed that bug with GM_log and GM_set/getValue always
taking the last namespace :-).

-------------- next part --------------
A non-text attachment was scrubbed...
Name: greasemonkey.xpi
Type: application/x-xpinstall
Size: 46170 bytes
Desc: not available
Url : http://mozdev.org/pipermail/greasemonkey/attachments/20050720/6e7e524b/greasemonkey-0001.bin
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mozdev.org/pipermail/greasemonkey/attachments/20050720/6e7e524b/test-0001.html
-------------- next part --------------
A non-text attachment was scrubbed...
Name: test.user.js
Type: application/x-javascript
Size: 3101 bytes
Desc: not available
Url : http://mozdev.org/pipermail/greasemonkey/attachments/20050720/6e7e524b/test.user-0001.js

More information about the Greasemonkey mailing list