Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Security: scope restrictions and wrappers

2 views
Skip to first unread message

Olivier

unread,
Oct 29, 2009, 3:24:05 PM10/29/09
to
Hi,

When accessing a content JS function from chrome-land (with FF3.5.3),
attempting to walk the call-stack back up to chrome-land using
arguments.callee.caller throws a "permission denied" exception (which
is a Good Thing™).
What part of FF security arsenal is responsible for this behavior?
SJOW? XOW? Something else?

Tiebreaker: i'd like to have the same kind of protection applied to a
Components.utils.Sandbox (that deals with content JS). Can it be done?

I've tried googling the documentation, asking #extdev and #developers,
to no avail...
Thank you in advance for any hint that would put me on the right
track.
Greetings,

Olivier

Blake Kaplan

unread,
Oct 30, 2009, 12:12:29 PM10/30/09
to
Olivier <o.c...@gmail.com> wrote:
> When accessing a content JS function from chrome-land (with FF3.5.3),
> attempting to walk the call-stack back up to chrome-land using
> arguments.callee.caller throws a "permission denied" exception (which
> is a Good Thing???).

> What part of FF security arsenal is responsible for this behavior?
> SJOW? XOW? Something else?

arguments.callee.caller is a special case where the JS engine actually does a
security check before allowing you to walk up the stack more than you should
be allowed to.

> Tiebreaker: i'd like to have the same kind of protection applied to a
> Components.utils.Sandbox (that deals with content JS). Can it be done?

I'm actually working on this. I *think* that COW (chrome object wrappers) and
<https://bugzilla.mozilla.org/show_bug.cgi?id=386635> might do what you want.
I don't remember seeing your question in #developers or I would have tried to
answer. Do note that because of limitations in SJOWs, instead of getting a
"permission denied" error, the accessing .caller will simply return null...

What are you trying to do?
--
Blake Kaplan

Olivier

unread,
Oct 31, 2009, 11:09:52 AM10/31/09
to
On Oct 30, 5:12 pm, Blake Kaplan <mrb...@gmail.com> wrote:

> Olivier <o.co...@gmail.com> wrote:
> > When accessing a content JS function from chrome-land (with FF3.5.3),
> > attempting to walk the call-stack back up to chrome-land using
> > arguments.callee.caller throws a "permission denied" exception (which
> > is a Good Thing???).
> > What part of FF security arsenal is responsible for this behavior?
> > SJOW? XOW? Something else?
>
> arguments.callee.caller is a special case where the JS engine actually does a
> security check before allowing you to walk up the stack more than you should
> be allowed to.

Alright. I had expected that it would be a mechanism generic enough to
be easily applied to my Sandbox case (like adding a wrapper or
initializing the Sandbox with a protected URI)...

> > Tiebreaker: i'd like to have the same kind of protection applied to a
> > Components.utils.Sandbox (that deals with content JS). Can it be done?
>
> I'm actually working on this. I *think* that COW (chrome object wrappers) and
> <https://bugzilla.mozilla.org/show_bug.cgi?id=386635> might do what you want.
> I don't remember seeing your question in #developers or I would have tried to
> answer. Do note that because of limitations in SJOWs, instead of getting a
> "permission denied" error, the accessing .caller will simply return null...
>
> What are you trying to do?

FWIW, i believe i asked the question on #developers wednesday evening
(CET). Anyway, thanks for your reply here. :-)

I'm working on GreaseMonkey. We are trying to address several
usability issues that arise from systematic XPCNWrapping in the
Sandbox. More specifically, we'd like to allow interaction between
userscript and content JS (replacing content objects with userscript
ones, registering userscript-defined callbacks, etc), which isn't safe
as of Gecko 1.9.1.

The main problem with accessing content JS is that content may acquire
a reference back to the Sandbox. There are two ways that i can see
that this may be achieved:
1. by customizing JS hooks (like getters/setters, valueOf, watch,
toString?) and walking up the call-stack:
arguments.callee.caller.__parent__
2. when passing a userscript-defined object as a parameter to a
content JS function: aParam.__parent__

From what i read in <https://wiki.mozilla.org/
XPConnect_Chrome_Object_Wrappers>, COWs do not seem to address this
“scope escalation” problem. I suppose it's fair as chrome-land element
appear immune to such attacks (thanks to the above mentioned JS engine
security checks), which is not the case of Sandbox objects initialized
with a content
URI/Window.

Is this description clear enough?

--
Olivier

PS: As we ignore evalInSandbox() return value in GM, i guess bug
386635 is not relevant to us.

Blake Kaplan

unread,
Nov 5, 2009, 10:49:20 AM11/5/09
to
Olivier <o.c...@gmail.com> wrote:
> Alright. I had expected that it would be a mechanism generic enough to
> be easily applied to my Sandbox case (like adding a wrapper or
> initializing the Sandbox with a protected URI)...

Yeah, you can't even do this from C++, so trunk builds actually sever the
stack chain when you call through a SJOW. This is less than ideal for
debugging but actually solves the problem you mention below (about
arguments.callee.caller walking).

> I'm working on GreaseMonkey. We are trying to address several
> usability issues that arise from systematic XPCNWrapping in the
> Sandbox. More specifically, we'd like to allow interaction between
> userscript and content JS (replacing content objects with userscript
> ones, registering userscript-defined callbacks, etc), which isn't safe
> as of Gecko 1.9.1.

So, the purpose of COWs is to make this safe (to let chrome provide JS
function callbacks to content). Hopefully the switch will be transparent:
setting sjow.foo = function foocallback(){} will automatically wrap
foocallback in a COW and things will Magically Work.

> 1. by customizing JS hooks (like getters/setters, valueOf, watch,
> toString?) and walking up the call-stack:
> arguments.callee.caller.__parent__

Yeah, this is "fixed" by the changes to SJOWs. It's not pretty, but it works.

> 2. when passing a userscript-defined object as a parameter to a
> content JS function: aParam.__parent__

And this is fixed by COWs (which explicitly don't allow you to get the
__parent__ of a COW'd object)... furthermore, the actual COW object actually
comes from content code, so other methods of getting the parent won't leak the
sandbox.

> PS: As we ignore evalInSandbox() return value in GM, i guess bug
> 386635 is not relevant to us.

Yeah, mostly.
--
Blake Kaplan

0 new messages