Re: [webcomponents] Encapsulation and defaulting to open vs closed (was in www-style)

On Feb 12, 2014, at 4:04 PM, Alex Russell <slightlyoff@google.com> wrote:

> 
> 
> In discussion with Elliot and Erik, there appears to be an additional complication: any of the DOM manipulation methods that aren't locked down (marked non-configurable and filtered, ala caja) create avenues to get elements from the Shadow DOM and then inject styles. E.g., even with Arv's lockdown sketch: 
> 
>   https://gist.github.com/arv/8857167
> 
> You still have most of your work ahead of you. DocumentFragment provides tons of "ins", as will all incidentally composed APIs.

I'm not totally clear on what you're saying. I believe you're pointing out that injecting hooks into the scripting environment a component runs in (such as by replacing methods on global protototypes) can allow the shadow root to be accessed even if no explicit access is given. I agree. This is not addressed with simple forms of Type 2 encapsutation. It is a non-goal for Type 2.

> 
> This is fraught.

Calling something fraught is not an argument.

> To get real ocap-style denial of access to the shadow DOM, we likely need to intercept and check all DOM accesses. Is the system still usable at this point? It's difficult to know. In either case, a system like caja *can* exist without explicit support....which raises the question: what's the goal? Is "Type 2" defined by real denial of access? Or is the request for a fig-leaf (perception of security)?

Type 2 is not meant to be a security mechanism. It is meant to be an encapsulation mechanism. Let me give a comparison. Many JavaScript programmers choose to use closures as a way to store private data for objects. That is an encapsulation mechanism. It is not, in itself, a hard security mechanism. If the caller can hook your global environment, and for example modify commonly used Object methods, then they may force a leak of your data. But that does not mean using closers for data hiding is a "fig-leaf" or "attractive nuisance". It's simply taking access to internals out of the toolset of common and convenient things, thereby reducing the chance of a caller inadvertently coming to depend on implementation details. ES6 private symbols serve a similar role. The proposal is merely to provide the same level of protection for the shadow DOM.

> 
> This is the struggle I have with Type 2. I can get my mind around Type 4 and want it very badly. So badly, in fact, that I bore most people I talk to with the idea of creating primitives that explain x-origin iframes (some sort of "renderer worker", how are the graphics contexts allocated and protected? what does it mean to navigate? what sorts of constraints can we put on data-propagation approaches for flowed layouts that can keep us out of security hell?).

(1) The form of Type 1 encapsulation offered by current Shadow DOM specs cannot explain *any* built-in element that has a compound structure. Because built-in elements do not expose their Shadow DOM. It would be nearly impossible to do that and code them safely. If you want explanatory power for built-ins, Type 1 is not sufficient.

(2) Enabling iframes to be implemented as a custom element would be hard, and goes beyond the bare minimum of Type 4 requirements. That said, as far as I can tell there is no need whatsoever to expose the details of how graphics contexts are allocated to enable this. Why would you think that? As I understand it, iframes are primarily about providing a security boundary with some tiny narrowly scoped holes, not about management of graphics resources. You would not use canvas-level primitives to implement iframes. 

> What I don't understand is what daylight there can be, in practice, between Type 2 and Type 4-by-other-means. Either we lean on convention (using class names for styling) and see how it goes, potentially extracting something like the previously-proposed "::part()" system, or we go down the caja-style rabbit hole and try to lock down _all_ the things, and not just from incidental access.
> 
> Where would you have us draw this line?

I would draw the line between simple, obvious explicit mechanisms whose intended common use amounts to free-form access to the Shadow DOM, and mechanisms that indirectly allow this access by injecting traps into the global environment. Providing a clean global environment is not a goal for Type 2. Nor is a secure membrane for method calls.

> 
> Until we can agree on this, Type 2 feels like an attractive nuisance

I think you are only calling it an "attractive nuisance" because you did not understand what it is meant to provide, and instead believe it is a broken version of a different feature. It is not. I have tried to explain. I hope my explanation was informative.

> and, on reflection, one that I think we should punt to compilers like caja in the interim. If toolkits need it, I'd like to understand those use-cases from experience.

Caja cannot solve the Type 2 or Type 4 use cases at all. Caja can be used by the embedder to protect the embedding page from content that it chooses to embed, by validating that it has been transpiled with Caja. But it cannot be used by an embedded component to protect itself from the embedding page. The component has no way to force the page to run all of its script through the Caja compiler, nor to verify that it has done so. If you think more about the security issues I expect it will be clear why it does not solve the problem.

Regards,
Maciej

Received on Thursday, 13 February 2014 21:26:19 UTC