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