I'm researching and experimenting with user script related stuff,
outside the scope of Greasemonkey, while on my gm-dev hiatus. One of
the questions I've wanted a good answer to for quite a while, but
never had a good one was, simply: Why is unsafeWindow unsafe? People,
including me have asked, [1], [2], more?.
Not is it; I trust that it is. I just like to know why, to be
informed. And there hasn't been, or I've never seen, an answer.
Well, I've managed to answer it myself. I tried out a few things and
found out how to exploit it. So the answer to why is:
Accessing any property of unsafeWindow AT ALL will completely expose
all of the privileged GM_ functions to the content page.
+2 Very good! I had already shown, also based on a slight modification of your original test, that content could expose the *text* of the userscript accessing unsafe members; in particular making them inappropriate for storing passwords an other sensible information.
But this one is the definitive proof of concept. I think you should publish this in the wiki asap and make the folks at greasemonkey-users and possible at us.o aware of this.
Specially the problem with unauthorized cross-site requests should be emphasised, since cookies are automatically sent with them; this means that if you had just visited your online bank and did not remove cookies after that (even if you have closed all your tabs) your bank account is open for the whole world. This, combined with the well known css-hack for detecting whether you have recently visited some among a number of given sites (for example popular online banks, amazon, ebay, etc) makes using unsafeWindow in the wild suicidal.
On Jan 12, 2008 5:52 AM, arantius <arant...@gmail.com> wrote:
> I'm researching and experimenting with user script related stuff, > outside the scope of Greasemonkey, while on my gm-dev hiatus. One of > the questions I've wanted a good answer to for quite a while, but > never had a good one was, simply: Why is unsafeWindow unsafe? People, > including me have asked, [1], [2], more?.
> Not is it; I trust that it is. I just like to know why, to be > informed. And there hasn't been, or I've never seen, an answer. > Well, I've managed to answer it myself. I tried out a few things and > found out how to exploit it. So the answer to why is:
> Accessing any property of unsafeWindow AT ALL will completely expose > all of the privileged GM_ functions to the content page.
RodMcguire wrote: > That hack might be used in GreaseMonkey itself to give user scripts > access to their global object, which as of now they can't see.
I read that page, ran some tests, and I still don't understand. The problem I'm having with Venkman seems to have something to do with the way evalInSandbox works; the errors and exceptions aren't noticed. The scope stuff makes no sense at all to me, since the following tests all seem to work as I'd expect:
Note that call() with a null or undefined argument sets "this" to the global object. Also, you *shouldn't* be able to add or override properties on a wrapped object; that's the entire point of the wrapper.
So ... what is does this hack fix?
I can at least understand some confusion about "this" versus "window", since the test this === window is true on a normal page. The magic of sandboxes and wrappers makes things significantly more complicated ...
I could not think of any fix for this that is backwards compatible. As a quick fix, the only thing I could come up with is a confirmation dialog before any cross-domain XHR.
I started hacking this up. It's not quite done yet, but I wanted to get people's thoughts. I know dialogs are never ideal. After this is pushed out we can think about better long-term options.
> +2 > Very good! I had already shown, also based on a slight modification > of your original test, that content could expose the *text* of the > userscript accessing unsafe members; in particular making them > inappropriate for storing passwords an other sensible information.
> But this one is the definitive proof of concept. I think you should > publish this in the wiki asap and make the folks at greasemonkey-users > and possible at us.o aware of this.
> Specially the problem with unauthorized cross-site requests should be > emphasised, since cookies are automatically sent with them; this > means that if you had just visited your online bank and did not remove > cookies after that (even if you have closed all your tabs) your bank > account is open for the whole world. This, combined with the well > known css-hack for detecting whether you have recently visited some > among a number of given sites (for example popular online banks, > amazon, ebay, etc) makes using unsafeWindow in the wild suicidal.
> On Jan 12, 2008 5:52 AM, arantius <arant...@gmail.com> wrote:
> > I'm researching and experimenting with user script related stuff, > > outside the scope of Greasemonkey, while on my gm-dev hiatus. One of > > the questions I've wanted a good answer to for quite a while, but > > never had a good one was, simply: Why is unsafeWindow unsafe? People, > > including me have asked, [1], [2], more?.
> > Not is it; I trust that it is. I just like to know why, to be > > informed. And there hasn't been, or I've never seen, an answer. > > Well, I've managed to answer it myself. I tried out a few things and > > found out how to exploit it. So the answer to why is:
> > Accessing any property of unsafeWindow AT ALL will completely expose > > all of the privileged GM_ functions to the content page.
> I could not think of any fix for this that is backwards compatible. As > a quick fix, the only thing I could come up with is a confirmation > dialog before any cross-domain XHR.
> I started hacking this up. It's not quite done yet, but I wanted to > get people's thoughts. I know dialogs are never ideal. After this is > pushed out we can think about better long-term options.
> I also attached a pic of the new dialog to this mail.
> - a
> On Jan 12, 2008 4:35 AM, esquifit <esqui...@googlemail.com> wrote:
> > +2 > > Very good! I had already shown, also based on a slight modification > > of your original test, that content could expose the *text* of the > > userscript accessing unsafe members; in particular making them > > inappropriate for storing passwords an other sensible information.
> > But this one is the definitive proof of concept. I think you should > > publish this in the wiki asap and make the folks at greasemonkey-users > > and possible at us.o aware of this.
> > Specially the problem with unauthorized cross-site requests should be > > emphasised, since cookies are automatically sent with them; this > > means that if you had just visited your online bank and did not remove > > cookies after that (even if you have closed all your tabs) your bank > > account is open for the whole world. This, combined with the well > > known css-hack for detecting whether you have recently visited some > > among a number of given sites (for example popular online banks, > > amazon, ebay, etc) makes using unsafeWindow in the wild suicidal.
> > On Jan 12, 2008 5:52 AM, arantius <arant...@gmail.com> wrote:
> > > I'm researching and experimenting with user script related stuff, > > > outside the scope of Greasemonkey, while on my gm-dev hiatus. One of > > > the questions I've wanted a good answer to for quite a while, but > > > never had a good one was, simply: Why is unsafeWindow unsafe? People, > > > including me have asked, [1], [2], more?.
> > > Not is it; I trust that it is. I just like to know why, to be > > > informed. And there hasn't been, or I've never seen, an answer. > > > Well, I've managed to answer it myself. I tried out a few things and > > > found out how to exploit it. So the answer to why is:
> > > Accessing any property of unsafeWindow AT ALL will completely expose > > > all of the privileged GM_ functions to the content page.
On Jan 12, 2008 10:06 PM, Aaron Boodman <bo...@youngpup.net> wrote:
> Ouch, nice find.
> I could not think of any fix for this that is backwards compatible.
Out of curiosity, which incompatible fixes did you consider? With a bit of luck, with an evolved community-infused-ideas take on one of them, we might come up with some solution which is only bad on the approximate level of the badness induced by going from old-GM-disastrous to XPCNativeWrapper-bad.
(Got to love my optimism, eh? ;-)
So, brainstorming-think: backwards-incompatible fixes are okay, until we decide on an action approach, where we trim down our options to least-bad alternative, padded up with as much backwards-compat as we can. Venting ideas and half-ideas good. My unresearched dreams and hopes later down this mail might be around or just past the boundary where the ideas are just noise, but we probably won't be drowned in that kind of thing anyway, so fire away if you have anything remotely useful, I'd say.
> As a quick fix, the only thing I could come up with is a confirmation > dialog before any cross-domain XHR.
> I started hacking this up. It's not quite done yet, but I wanted to > get people's thoughts. I know dialogs are never ideal. After this is > pushed out we can think about better long-term options.
-1. This is a Vista:esque dialog, insofar as it provides too little information to support the user's answer to the question, which will teach users to learn a click-through behaviour for all the typical false alarms it will yield, followed by a "well, you brought it down on yourself; GM *did* ask whether you wanted to empty your bank account, so it's really your own fault".
As an absolute minimum, the dialog should postulate, very clearly, *which script* is doing the request. (That's doable by offering each script a unique GM_xmlHttpRequest bound to invoke the dialog in its own name.)
Further on, the same origin policy is mis-applied, as the user script circumstances don't map to those where the (already bad, though convention bound) same domain policy jail, which kind-of-works in the web jail metaphor which to a much lesser extent applies to GM scripts. I'd argue that the "same domain" compared to which *would* make a GM script apply the same model would be the domain the script was *loaded from*. Especially as a script missing any @include header applies to *. Which means that as long as you access your bank, with a @include * malicious script, the dialog wouldn't even show, and the ideal user, having been taught that there's a dialog to protect her from xhr theft, won't see one. For the typical case, that would bring down the problem to "exploits towards userscripts.org", while resulting in way more annoying dialogs teaching users the dialog asks a question they probably considered themselves to have answered already on install time.
I know, this is not exceptionally constructive criticism, in that I don't have a patent solution that is Good to offer instead of the dialog, but, by my perceptions, the problem we should focus on is breaking the call chain that exposes either or both of rapFoo.caller and rapFoo.caller.__parent__, or figure out ways of architecting in tainting code which would introduce a privilege boundary firewall from page context code reaching for GM context code. (And yes -- without any idea of how that might be done, that qualifies as a non-tip. :-/)
I'm very much in favour of beating the drums about unsafeWindow based scripts being worth big "Danger, Will Robinson!" warnings on us.o and the like, and that is as true now as it's been all along, plus the added community awareness of exactly how it's exploitable. But I don't feel that the dialog is a net improvement on the problem. (Not that I'll be all sour grapes if 0.8 gets one; I just want to voice my position.)
arantius wrote: > I'm researching and experimenting with user script related stuff, > outside the scope of Greasemonkey, while on my gm-dev hiatus. One of > the questions I've wanted a good answer to for quite a while, but > never had a good one was, simply: Why is unsafeWindow unsafe? People, > including me have asked, [1], [2], more?.
> Not is it; I trust that it is. I just like to know why, to be > informed. And there hasn't been, or I've never seen, an answer. > Well, I've managed to answer it myself. I tried out a few things and > found out how to exploit it. So the answer to why is:
> Accessing any property of unsafeWindow AT ALL will completely expose > all of the privileged GM_ functions to the content page.
I think (though I still haven't done any testing) this was fixed with the new XPCSafeJSObjectWrapper [1][2] introduced in Firefox 3. That still leaves us with a large security hole until we stop supporting Firefox 2 and below, or until the fix gets applied in a Firefox 2 release.
esquifit wrote: > On Jan 13, 2008 11:32 AM, Gareth Andrew <gingerhend...@gmail.com> wrote:
>> I haven't looked into this in any detail, but I can't reproduce the >> exploit on Firefox 3b2. Anybody else tried? Maybe there's a glimmer of >> hope?
> You are right, I cannot reproduce it on 3b2 either.
On Jan 13, 2008 12:27 AM, Johan Sundström <oyas...@gmail.com> wrote:
> Out of curiosity, which incompatible fixes did you consider? With a > bit of luck, with an evolved community-infused-ideas take on one of > them, we might come up with some solution which is only bad on the > approximate level of the badness induced by going from > old-GM-disastrous to XPCNativeWrapper-bad.
The first thing I considered was checking the caller chain for __parent__ == unsafeWindow as you suggest below. I suspected that would break some scripts, so tried to find something that would not.
Another idea is to change GM_xhr to not send cookies for x-domain. This would obviously break some scripts that rely on you being logged into various services to interact with them. I looked into using XHR without cookies once before for another project and couldn't figure it out, so I don't know how viable that option is.
BTW, I finished the dialog last night and tested it on some us.o scripts, and it is not that great. Lots of scripts make GM_xhr requests to their homepage on page load for autoupdate. This is completely unrelated to the page that you're viewing, so it's very confusing to get the dialog.
So I think I'm going to try the call-chain checking thing next. It might catch too many scripts, but it only needs to affect cross-domain requests, and only FF2. I think you could also narrow it further to GM_xhr requests after an unsafeWindow access.
> So, brainstorming-think: backwards-incompatible fixes are okay, until > we decide on an action approach, where we trim down our options to > least-bad alternative, padded up with as much backwards-compat as we > can. Venting ideas and half-ideas good. My unresearched dreams and > hopes later down this mail might be around or just past the boundary > where the ideas are just noise, but we probably won't be drowned in > that kind of thing anyway, so fire away if you have anything remotely > useful, I'd say.
Definitely, sorry if I was brisk. I just want to get some fix in place quickly.
> > As a quick fix, the only thing I could come up with is a confirmation > > dialog before any cross-domain XHR.
> > I started hacking this up. It's not quite done yet, but I wanted to > > get people's thoughts. I know dialogs are never ideal. After this is > > pushed out we can think about better long-term options.
> -1. This is a Vista:esque dialog, insofar as it provides too little > information to support the user's answer to the question, which will > teach users to learn a click-through behaviour for all the typical > false alarms it will yield, followed by a "well, you brought it down > on yourself; GM *did* ask whether you wanted to empty your bank > account, so it's really your own fault".
> As an absolute minimum, the dialog should postulate, very clearly, > *which script* is doing the request. (That's doable by offering each > script a unique GM_xmlHttpRequest bound to invoke the dialog in its > own name.)
Unfortunately, that isn't possible. All scripts play together in unsafeWindow, the page could grab any one of their GM_xhr instances.
> Further on, the same origin policy is mis-applied, as the user script > circumstances don't map to those where the (already bad, though > convention bound) same domain policy jail, which kind-of-works in the > web jail metaphor which to a much lesser extent applies to GM scripts. > I'd argue that the "same domain" compared to which *would* make a GM > script apply the same model would be the domain the script was *loaded > from*. Especially as a script missing any @include header applies to > *. Which means that as long as you access your bank, with a @include * > malicious script, the dialog wouldn't even show, and the ideal user, > having been taught that there's a dialog to protect her from xhr > theft, won't see one. For the typical case, that would bring down the > problem to "exploits towards userscripts.org", while resulting in way > more annoying dialogs teaching users the dialog asks a question they > probably considered themselves to have answered already on install > time.
It seems like @include * (or other messed up @includes) is a separate issue... We should separately teach user script developers to be careful with @include, and/or develop a new syntax.
> I know, this is not exceptionally constructive criticism, in that I > don't have a patent solution that is Good to offer instead of the > dialog, but, by my perceptions, the problem we should focus on is > breaking the call chain that exposes either or both of rapFoo.caller > and rapFoo.caller.__parent__, or figure out ways of architecting in > tainting code which would introduce a privilege boundary firewall from > page context code reaching for GM context code. (And yes -- without > any idea of how that might be done, that qualifies as a non-tip. :-/)
Nah, it's good. I'll check this one next.
> I'm very much in favour of beating the drums about unsafeWindow based > scripts being worth big "Danger, Will Robinson!" warnings on us.o and > the like, and that is as true now as it's been all along, plus the > added community awareness of exactly how it's exploitable. But I don't > feel that the dialog is a net improvement on the problem. (Not that > I'll be all sour grapes if 0.8 gets one; I just want to voice my > position.)
Thanks, I appreciate it.
If anyone wants to help with coding, there is one thing that could be done in parallel for someone who has a mac handy.
It would be nice if this fix also enabled FF3 support so that users who have broken scripts have a workaround: upgrade to FF3b2. However, openInEditor() is broken in FF3 on the 0.7 branch. The latest version of utils.js on trunk fixes it for Windows, but it breaks for mac. I think there are two solutions:
* openInEditor() references an interface called nsILocalFileMac. I think this interface is actually called something weird in FF3b2 like nsILocalFileMac_GECKO_18_BRANCH or something like that. Changing to that might fix it.
* Test for mac some other way and then use the old code for mac and the new code for windows/linux (the old code works on mac in FF3).
If nobody has time, nbd, I can do this myself after.
I'll be in #greasemonkey on freenode if anyone's around and wants to chat,
> I think (though I still haven't done any testing) this was fixed with > the new XPCSafeJSObjectWrapper [1][2] introduced in Firefox 3. That > still leaves us with a large security hole until we stop supporting > Firefox 2 and below, or until the fix gets applied in a Firefox 2 release.
> esquifit wrote: > > On Jan 13, 2008 11:32 AM, Gareth Andrew <gingerhend...@gmail.com> wrote:
> >> I haven't looked into this in any detail, but I can't reproduce the > >> exploit on Firefox 3b2. Anybody else tried? Maybe there's a glimmer of > >> hope?
> > You are right, I cannot reproduce it on 3b2 either.
I am a bit confused by all this. Anyway, I think the problem does not only affect the GM_* API; if one attempt to enumerate the members of the gmScope object in Anthony's example, one gets:
* window: [object XPCNativeWrapper [object Window]] * unsafeWindow: [object Window] * document: [object XPCNativeWrapper [object HTMLDocument]] * XPathResult: nsIDOMXPathResult * GM_addStyle: function (css) { GM_addStyle(safeDoc, css); } * GM_log: function () { <the code>} * GM_setValue: function () { <the code> } * GM_getValue: function () {<the code> } * GM_openInTab: function () { <the code>} * GM_xmlhttpRequest: function () { <the code>; } * GM_registerMenuCommand: function () { <the code> } * addEventListener: function XPCNativeWrapper function wrapper() { [native code] } * top: [object XPCNativeWrapper [object Window]] * self: [object XPCNativeWrapper [object Window]] * setTimeout: function XPCNativeWrapper function wrapper() { [native code] } * alert: function XPCNativeWrapper function wrapper() { [native code] } * getInterface: function XPCNativeWrapper function wrapper() { [native code] } * navigator: [object XPCNativeWrapper [object Navigator]] * location: <the url where you are testing this> * console: [object Object]
Any of these objects can be overridden by the attacking page (I confirmed it). I do not know whether jumping into the browser scope is possible, or whether one could do nasty things with the console object when it points to firebug's console. But even if we were not able to redefine these functions we could still make things like instructing the browser to open 1000000 tabs, cluttering the prefs.js file with trash (well, prefs.js gets written back when exiting firefox, but we could then exhaust the available memory by creating enough entries in the prefs store), etc. So fixing GM_XHR does not seems to be the definite solution, though the highest priority at any rate.
On Jan 13, 3:26 pm, esquifit <esqui...@googlemail.com> wrote:
> I am a bit confused by all this. Anyway, I think the problem does not
> only affect the GM_* API; if one attempt to enumerate the members of
> the gmScope object in Anthony's example, one gets:
Is that where userscript functions and variables are stored too?
On Jan 13, 2008 12:40 PM, RodMcguire <mcgu...@telerama.com> wrote:
> On Jan 13, 3:26 pm, esquifit <esqui...@googlemail.com> wrote: > > I am a bit confused by all this. Anyway, I think the problem does not > > only affect the GM_* API; if one attempt to enumerate the members of > > the gmScope object in Anthony's example, one gets:
> Is that where userscript functions and variables are stored too?
Yeah. I agree that XHR is the highest priority, that's what I'm focusing on.
On 13 Gen, 21:40, RodMcguire <mcgu...@telerama.com> wrote:
> On Jan 13, 3:26 pm, esquifit <esqui...@googlemail.com> wrote:
> > I am a bit confused by all this. Anyway, I think the problem does not
> > only affect the GM_* API; if one attempt to enumerate the members of
> > the gmScope object in Anthony's example, one gets:
> Is that where userscript functions and variables are stored too?
Apparently not. I had also tried setting a var foo='bar' in the
userscript, but both gmScope.foo and gmScope.window.foo returned
'undefined'.
> > Is that where userscript functions and variables are stored too?
> Apparently not. I had also tried setting a var foo='bar' in the
> userscript, but both gmScope.foo and gmScope.window.foo returned
> 'undefined'.
In some past discussion on this issue I recall someone saying that a
userscript was wrapped inside an anonymous function so that all
functions and variables lived there. I never heard a reason of why.
On Jan 13, 2008 7:29 PM, RodMcguire <mcgu...@telerama.com> wrote:
> In some past discussion on this issue I recall someone saying that a > userscript was wrapped inside an anonymous function so that all > functions and variables lived there. I never heard a reason of why.
Way in the past Greasemonkey scripts were wrapped inside an anonymous function to prevent them from accidentally interacting with their environment. This wasn't really a security thing but a sanity thing. It was meant to prevent your script from breaking when the global context of the content page changed. It didn't work well, those were early days.
With mozilla's addition of the Sandbox object, Greasemonkey no longer needed to wrap things in an anonymous function because the sandbox does the right thing -- provide a totally separate context. But by that time lots of scripts relied on the wrapper function by using the "return" statement in top level code. So, I left it in for compatibility.
But you're right, that explains why var foo = "foo" doesn't show up on the sandbox.
Maybe Greasemonkey script headers need a "@version" entry. That way
new scripts that specify a @version live in a normal environment where
they can access the Global Object, while legacy scripts still get
wrapped in an anonymous function where a top level "return" works.
Having the Global Object accessible makes things a lot easier for
debuggers.
On Jan 13, 10:48 pm, "Aaron Boodman" <bo...@youngpup.net> wrote:
> On Jan 13, 2008 7:29 PM, RodMcguire <mcgu...@telerama.com> wrote:
> > In some past discussion on this issue I recall someone saying that a
> > userscript was wrapped inside an anonymous function so that all
> > functions and variables lived there. I never heard a reason of why.
> Way in the past Greasemonkey scripts were wrapped inside an anonymous
> function to prevent them from accidentally interacting with their
> environment. This wasn't really a security thing but a sanity thing.
> It was meant to prevent your script from breaking when the global
> context of the content page changed. It didn't work well, those were
> early days.
> With mozilla's addition of the Sandbox object, Greasemonkey no longer
> needed to wrap things in an anonymous function because the sandbox
> does the right thing -- provide a totally separate context. But by
> that time lots of scripts relied on the wrapper function by using the
> "return" statement in top level code. So, I left it in for
> compatibility.
> But you're right, that explains why var foo = "foo" doesn't show up on
> the sandbox.
I tested this on many user scripts and compat looks good, but there is clearly room for some problems, if scripts integrated with sites using GM_xhr and expected login to work. Users of those scripts could potentially be directed to update to FF3b.
The general idea is that although you can get to GM functions, you can't do much damage with them. For example, you could fill up the preferences store or open tabs, but I'm not as worried about those kind of attacks.
===
Other approaches that I tried which didn't work:
Checking the call stack. The idea was that I would walk the stack looking for a function whose __parent__ was from content. If found, the request would be denied. This did not work because anonymous functions do not have a __parent__ value. Therefore it is impossible to tell the difference between anonymous functions from chrome and those from content. It might be possible to work around this, but I don't know how without help from Mozilla.
Next I tried disallowing access to cross-domain xhr after an access to unsafeWindow. Unfortunately, I could not find a way to track access to unsafeWindow. __defineGetter__ does not work work on Greasemonkey's sandbox. This is the same wall that Johan has hit before (http://ecmanaut.blogspot.com/2007/08/extending-greasemonkey-by-way-of...). Again, I need help from Mozilla to get any farther with this approach.
===
I'd like to push a build with this change soon, but I think that first I should check with Mozilla to make sure I haven't missed anything on the other two options.
In the meantime, what do people think of this fix?
On 14 Jan., 04:48, "Aaron Boodman" <bo...@youngpup.net> wrote:
> With mozilla's addition of the Sandbox object, Greasemonkey no longer
> needed to wrap things in an anonymous function because the sandbox
> does the right thing -- provide a totally separate context. But by
> that time lots of scripts relied on the wrapper function by using the
> "return" statement in top level code. So, I left it in for
> compatibility.
> But you're right, that explains why var foo = "foo" doesn't show up on
> the sandbox.
So, is local variables to this function not available to the website,
but global variables in the sandbox is? If so, maybe the GM_*
functions could be made function local.
On Jan 14, 2008 11:10 AM, Jesper Kristensen <goo...@jesperkristensen.dk> wrote:
> So, is local variables to this function not available to the website, > but global variables in the sandbox is? If so, maybe the GM_* > functions could be made function local.
This doesn't seem to work. I tried copying GM_* to a local and it throws an exception when user scripts try to call it.
I talked to Mozilla today and they gave me a good idea for a better fix using C++. I'm going to take a whack at it tonight (basically, walking the js call stack in C++, looking for functions not from the sandbox). That fix should work for all APIs and be completely transparent to user script developers.
They are also going to try and add a different layer of security for this problem from their side for 2.0.0.12, but no guarantees. Also, GM would have to be updated to take advantage of that fix, it wouldn't just start working automatically.
On Jan 15, 2008 5:33 AM, Aaron Boodman <bo...@youngpup.net> wrote:
> I talked to Mozilla today and they gave me a good idea for a better > fix using C++. I'm going to take a whack at it tonight (basically, > walking the js call stack in C++, looking for functions not from the > sandbox). That fix should work for all APIs and be completely > transparent to user script developers.
> They are also going to try and add a different layer of security for > this problem from their side for 2.0.0.12, but no guarantees. Also, GM > would have to be updated to take advantage of that fix, it wouldn't > just start working automatically.
Does either approach sever the __parent__ band trail that ties unsafeWindow accesses and other stuff from the user script sandbox stored on unsafeWindow?
I use the latter feature quite a lot, such as for adding DOM 0 style features to my browser:
and exposing more complex APIs and features to select web pages from code implementing them in Greasemonkey space -- occasionally even using the privileged GM functions -- and it's sad to find them all vulnerable to this huge exetent.
If they don't, I guess I'll live through it by upgrading to Firefox 3 myself, but it would be very nice to be able to share the good stuff with others who haven't or won't for quite some time still, without undermining their browser security.
On Jan 15, 2008 6:07 AM, Johan Sundström <oyas...@gmail.com> wrote:
> Does either approach sever the __parent__ band trail that ties > unsafeWindow accesses and other stuff from the user script sandbox > stored on unsafeWindow?
I didn't follow this, can you clarify?
> I use the latter feature quite a lot, such as for adding DOM 0 style > features to my browser:
This one would work. Even if the code were something like this:
unsafeWindow.__defineGetter__("foo", function() { // something that calls GM_*
});
I think it would still work because there is no function in that stack which is defined in content (whose global object is unsafeWindow, which is what I plan to test).
> and exposing more complex APIs and features to select web pages from > code implementing them in Greasemonkey space -- occasionally even > using the privileged GM functions -- and it's sad to find them all > vulnerable to this huge exetent.
Yeah, sorry. I'm not having a blast either.
> If they don't, I guess I'll live through it by upgrading to Firefox 3 > myself, but it would be very nice to be able to share the good stuff > with others who haven't or won't for quite some time still, without > undermining their browser security.
I don't think that I will be reducing what you can do here any more than what FF3 will do.
> I think it would still work because there is no function in that stack > which is defined in content (whose global object is unsafeWindow, > which is what I plan to test).
So just to be clear, the code I plan to implement would look something like (in JS pseudo-code):
function allowAccessToGM() { var fn = arguments.callee; while (fn) { if (!fnWasDefinedInGreasemonkey(fn) && !fnWasDefinedInSandbox(fn)) { return false; } fn = fn.caller; return true;
} }
So I just realized that one thing this would break is if content exposed a js api with a callback, and you used it and then called a GM api.
I don't know how to make that use-case work, but I think this is a pretty good tradeoff.