Is it easier (or more desirable) to make a function that clones a
trusted object, but changes the type so that the sandbox can't
reference trusted APIs from the clone?  Or, if the object is a
function, to make it so the sandbox can't introspect on the function?

On 3/10/06, Fritz Schneider <[EMAIL PROTECTED]> wrote:
> In case this was too verbose, I'll summarize: I'm suggesting that many
> applications that require cross-context communication might be solved
> with the combination of:
>
> (1) easy object (de)serialization to/from strings and
> (2) a proxy object that safely passes strings across contexts (via a
> proxy model, producer/consumer, or whatever)
>
> Perhaps I've reduced the problem to itself (how to protect the
> proxy?), but I don't think so: you can basically do this with the
> sandbox today, though it is a little ugly.
>
> On 3/9/06, Fritz Schneider <[EMAIL PROTECTED]> wrote:
> > Excellent, thanks for the response -- very helpful.
> >
> > In this particular instance we want to pass content from the page into
> > untrusted code, and then be able to have that code tell us a result
> > (also a primitive type, e.g., a string serialization of a map or
> > similar).
> >
> > Monica Chew (cc'd above) has implemented this safely using
> > evalInSandbox. Basically, she calls into a fixed interface in the
> > sandbox that returns a string containing a representation of the
> > content the untrusted code is interested in as well as the name of the
> > function(s) to invoke with that data. For example, "title,url,a:hrefs
> > || func1,func2,func3". The chrome driver then extracts these data from
> > the page,  stringifies them, and then pieces them together into a
> > string appropriate to eval in the sandbox. For example, "var data =
> > {title: <value>, url:
> > <value>,...};func1(data);func2(data);func3(data)".
> >
> > In the process of working this out, I was thinking two things.
> >
> > First, that the trouble arises from giving references to _objects_ in
> > other contexts, but that often the reference to an object is a means
> > rather than an end. For example, we wanted to do sandbox.foo =
> > functionInTrustedContext to enable passing of data out of the context.
> > I suspect that for many applications, passing reference types isn't
> > strictly necessary; we're can get by with passing data so long as
> > there is a way to pass it.
> >
> > So perhaps it might make sense to provide a safe, easy way to pass
> > _primitive data_ between contexts with different levels of trust. The
> > brower could provide a proxy service to do this. One context could
> > call:
> >
> > var targetContext = // a window, a sandbox, an xpcom context
> > function consumer() {...}
> > proxy.registerInterface(targetContext, consumer, "sendData");
> >
> > then in the target context code could call:
> >
> > // causes consumer(someValue) to be called in first context
> > proxy.sendData(someValue);
> > // or maybe just sendData(someValue)
> >
> > The proxy could enforce that someValue is a string, or could perhaps
> > do the serialization itself. I haven't thought this out much, but
> > perhaps there's something there.
> >
> > The second thought that I had was that you could actually safely
> > execute code in one context on behalf of another using a serialization
> > of there were an easy way stringify code (and there is!). Suppose you
> > have some code that wants to operate on content but that you don't
> > want to have access to chrome. The chrome piece could get the string
> > representation of the code (e.g., the serialization of an object
> > encapsulating state as well as functions) from the untrusted context
> > via the proxy-like thing. Then it could eval it in the content context
> > and receive the results through a proxy call from within the content
> > (you can prevent the content from making spurious calls by only
> > enabling them when you know you're evaling). Or maybe via a return
> > value.
> >
> > It's late and maybe I'm rambling, but I thought I'd throw it out
> > there. Or maybe people already do this kind of thing -- I haven't
> > looked at the state of the GM art in a while.
> >
> > On 3/9/06, Brendan Eich <[EMAIL PROTECTED]> wrote:
> > >  Fritz Schneider wrote:
> > >
> > >  This direction of access (untrusted is handed a "trusted" object by
> > > trusted code) is not safe.
> > >
> > >  Then it sounds like it is the case that there is no possible way to
> > > safely expose an interface to code in a sandbox?
> > >
> > >  We *think* we've secured the paths in the object graph that don't go
> > > through generic access checking code in window object get- and 
> > > set-property
> > > hooks.  We may have a few obscure paths to check, which are exposed only 
> > > on
> > > certain kinds of objects, which may not be exposed via Firefox chrome to
> > > content (extensions are another story...).
> > >
> > >  But, as noted earlier today in my previous reply, it seems like a bad 
> > > idea
> > > to rely on each trusted object to be fully trustworthy, since the trust
> > > comes from inheritance, specifically from URI origin being chrome -- a
> > > blanket judgment that doesn't address individual weak links.
> > >
> > >  So the greatest lower bound on trust labels for code active on the JS 
> > > stack
> > > gives us a small, central, easily audited piece of code to trust.  This
> > > "meet-computing" code automatically lowers privileges for all "trusted
> > > objects" whose methods might be called from untrusted code, even in very
> > > indirect ways.  There may still be covert channels, but we need to address
> > > this very overt one first.
> > >
> > >  Doing so sounds easier than it will prove to be, I bet.  I believe (bz 
> > > may
> > > remember off the top of his head) that we have code where content calls
> > > chrome (obvious example would be a dialog, say for a file upload widget or
> > > some such thing) and needs the callee to have greater privileges than the
> > > caller does.
> > >
> > >
> > >  I'm playing with some
> > > maybe-untrusted code in a sandbox, and was hoping to give it a way to
> > > pass information out to my trusted code (e.g., by attaching
> > > sandbox.foo = function() {} and letting the sandboxed code call foo),
> > > aside from the result of evalInSandbox.
> > >
> > >
> > >  We should talk more about the particulars.  Better yet, we should 
> > > implement
> > > the "meet" idea and diagnose the hard cases that it breaks, giving them
> > > better means to their hard-case ends.  That way everyone's safer by 
> > > default.
> > >
> > >
> > >
> > >
> > >  Doesn't seem to be able to (I get a security exception accessing
> > > .__proto__ on the privileged object).
> > >
> > >  That's because of one of those JS-level checks (JS calls the hook, the
> > > CAPS code implements it).
> > >
> > > We check __proto__, __parent__, <class-prototype>.constructor, and
> > > scripted getter or setter.
> > >
> > >  Why, though?
> > >
> > >
> > >  Because of the window-level access checks not sufficing in our extended
> > > world.  In the DOM same-origin model, windows are articulation points in 
> > > the
> > > graph of all objects, and also containers of objects that all have the 
> > > same
> > > trust label within a given window.  You can open another window and load a
> > > doc from a different origin in it.  You shouldn't be able to read data 
> > > from
> > > its DOM, though (you can write only to location, to navigate the window 
> > > away
> > > to another document).
> > >
> > >  So it is necessary to check access at window boundaries.  It's also
> > > sufficient to identify objects in each window by their window's trust 
> > > label,
> > > i.e. to link window and label, but not link every object in the window to
> > > the trust label (aka principal). Instead, we require security code that
> > > wishes to find the trust label for a contained object to follow the 
> > > object's
> > > static scope (or parent, in SpiderMonkey jargon) chain up to the window.
> > >
> > >  This avoids the cost of a trust-label slot per object, at the cost of 
> > > short
> > > loops up the scope chain.  (The scope chain link slot is unavoidable in
> > > SpiderMonkey and used by function objects and all DOM objects -- in 
> > > ECMA-262
> > > Edition 3 it is specified for function objects as the [[Scope]] internal
> > > property).  A user-constructed object obj whose constructor function is 
> > > Ctor
> > > has obj.__parent__ === Ctor.__parent__.  And top-level function objects 
> > > are
> > > parented by the global object, which is the window in the browser 
> > > embedding
> > > of JS.  So, most objects are scoped directly by their window, with the
> > > obvious exception of the DOM level 0, wherein objects nest as their tags 
> > > do
> > > (window contains document contains form contains form element contains 
> > > event
> > > handler).  Still, searching rather than linking every object to its
> > > principal is a good trade-off.
> > >
> > >  Window-boundary access checking may appear to be secure, since each 
> > > window
> > > gets its own copy of the JS standard objects, so all objects in a window,
> > > including the window itself, have Object.prototype as their ur-prototype
> > > object, and all objects are scoped by the window, which has a null scope
> > > chain link (__parent__ in SpiderMonkey).
> > >
> > >  But it's not secure to access-check only at the window boundaries in
> > > Mozilla, because of our JS extensions, some of which go back eight or more
> > > years:
> > >
> > >
> > > SpiderMonkey exposes not only Object.prototype__defineGetter__ and
> > > Object.prototype.__defineSetter__, but also
> > > Object.prototype.watch.  These are implemented internally using 
> > > per-property
> > > getters and setters, hooks that are peculiar to the property named by the
> > > method.  Therefore gets and sets on such properties, even if they are
> > > defined on a window object, bypass the class-generic window get- and
> > > set-property hooks that do the common access checking required for
> > > same-origin security.
> > >
> > > SpiderMonkey reflects __proto__ and __parent__ for all objects, again 
> > > using
> > > per-property getter and (for __parent__) setter hooks.  The ability to 
> > > bind
> > > chrome XBL makes these hazardous without specific access checking.  See
> > > https://bugzilla.mozilla.org/show_bug.cgi?id=296397.
> > > In the JS object model, a constructor function object C has a prototype, 
> > > and
> > > C.prototype.constructor === C.  Again XBL introduced hazards not found in
> > > the conventional DOM level 0 same-origin model.  This was originally
> > > reported in
> > > https://bugzilla.mozilla.org/show_bug.cgi?id=296489, which
> > > was dup'ed against 296397.
> > >  I will take the fifth on other hard cases, because I'm not sure the bugs
> > > have been patched in all older releases.
> > >
> > >  /be
> > >
> >
> _______________________________________________
> dev-security mailing list
> dev-security@lists.mozilla.org
> https://lists.mozilla.org/listinfo/dev-security
>
_______________________________________________
dev-security mailing list
dev-security@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-security

Reply via email to