Re: [webcomponents] Proposal for Cross Origin Use Case and Declarative Syntax

2013-11-12 Thread Ryosuke Niwa
On Nov 12, 2013, at 8:12 AM, Dimitri Glazkov dglaz...@chromium.org wrote:
 On Sun, Nov 10, 2013 at 6:49 PM, Arthur Barstow art.bars...@nokia.com wrote:
 On 11/9/13 3:24 AM, ext Ryosuke Niwa wrote:
 Hi all,
 
 We have been discussing cross-orign use case and declarative syntax of web 
 components internally at Apple, and here are our straw man proposal to amend 
 the existing Web Components specifications to support it.
 
 *1. Modify HTML Imports to run scripts in the imported document itself*
 
 This allows the importee and the importer to not share the same script 
 context, etc…
 
 This could be an option and shouldn’t be the default.

I don’t think we want to add a yet another flag to control the behavior.

 By running scripts in a different context, we are ejecting the primary use 
 case of enabling frameworks/libraries to better manage their assets and 
 dependencies (aka the Bootstrap use case).

That would force same-origin and cross-origin use cases to have different 
behaviors because we can’t run the untrusted script in the host document.

In particular, it’s important for the global (window) object to have a 
consistent behavior between untrusted cross-origin and trusted same-origin use 
cases.

 Rob Dodson’s article has a nice progression explaining the use case: 
 http://robdodson.me/blog/2013/08/20/exploring-html-imports/

I don’t think this blog post contains any argument for either behavior.

 Also, check out newly minted Eric Bidelman's article on imports (especially 
 the use cases section at the bottom): 
 http://www.html5rocks.com/en/tutorials/webcomponents/imports/

I see the following argument for the current behavior:
Script in the import is executed in the context of the window that contains the 
importingdocument. So window.document refers to the main page document. This 
has two useful corollaries:
functions defined in an import end up on window.
you don't have to do anything crazy like append the import's script blocks to 
the main page. Again, script gets executed.
What we’re proposing is to execute the script in the imported document so the 
only real argument is the point that “functions defined in an imported end up 
on window” (of the host document).

I think that’s a bad thing.  We don’t want imported documents to start 
polluting global scope without the user explicitly importing them.  e.g. 
import X in Python doesn’t automatically import stuff inside the module into 
your global scope.  To do that, you explicitly say “import * from X”.  
Similarly, “using std” is discouraged in C++.

I don’t think the argument that this is how external script and stylesheet fly 
either because the whole point of web components is about improving the 
modularity and reusability of the Web.

 Re: Custom Elements LC, this is an issue to handle in HTML Imports 
 specification, not related to Custom Elements. 
 
 
 *2. Add “importcomponents content attribute on link element*
 
 It defines the list of custom element tag names to be imported from the 
 imported HTML document.
 e.g. link rel=import href=~ importcomponents=tag-1 tag-2 will export 
 custom elements of tag names tag-1 and tag-2 from ~. Any name that didn't 
 have a definition in the import document is ignored (i.e. if tag-2 was not 
 defined in ~, it would be skipped but tag-1 will be still imported).
 
 This mechanism prevents the imported document from defining arbitrary 
 components in the host document.
 
 Re: Custom Elements LC, this should be handled in HTML Imports specification. 
 HTML Imports can rely on Custom Elements specification. Any additional hooks 
 that could be needed to facilitate this feature could be added in Custom 
 Elements Level 2 specification.
  
 
 *3. Support static (write-once) binding of a HTML template*
 
 e.g.
 template id=cardTemplateName: {{name}}brEmail:{{email}}/template
 script
 document.body.appendChild(cardTemplate.instantiate({name: Ryosuke Niwa, 
 email:rn...@webkit.org mailto:rn...@webkit.org}));
 /script
 
 This seems very similar to the Rafael Weinstein's MDV work. You guys should 
 collaborate :)

Yes, we had an informal discussion about it a couple of weeks ago, and we’re 
interested in continuing our discussion with him on public-webapps.

 Re: Custom Elements LC, this is unrelated to specification.
  
 *4. Add “interface content attribute to template element*
 
 This content attribute specifies the name of the JavaScript constructor 
 function to be created in the global scope. The UA creates one and will be 
 used to instantiate a given custom element. The author can then setup the 
 prototype chain as needed:
 
 template defines=name-card interface=NameCardElement
 Name: {{name}}brEmail:{{email}}
 /template
 script
 NameCardElement.prototype.name = function () {...}
 NameCardElement.prototype.email = function () {...}
 /script
 
 This is similar to doing:
 var NameCardElement = document.register(’name-card');
 
 This is another take on the declarative custom elements (a variant 

Re: [webcomponents] Proposal for Cross Origin Use Case and Declarative Syntax

2013-11-12 Thread Elliott Sprehn
On Tue, Nov 12, 2013 at 12:45 AM, Ryosuke Niwa rn...@apple.com wrote:

 [...]


- Script in the import is executed in the context of the window that
contains the importingdocument. So window.document refers to the main
page document. This has two useful corollaries:
   - functions defined in an import end up on window.
   - you don't have to do anything crazy like append the import's
   script blocks to the main page. Again, script gets executed.

 What we’re proposing is to execute the script in the imported document so
 the only real argument is the point that “functions defined in an imported
 end up on window” (of the host document).

 I think that’s a bad thing.  We don’t want imported documents to start
 polluting global scope without the user explicitly importing them.  e.g. 
 import
 X in Python doesn’t automatically import stuff inside the module into
 your global scope.  To do that, you explicitly say “import * from X”.
  Similarly, “using std” is discouraged in C++.

 I don’t think the argument that this is how external script and stylesheet
 fly either because the whole point of web components is about improving the
 modularity and reusability of the Web.


What you're proposing breaks a primary use case of:

link rel=import href=//apis.google.com/jquery-ui.html

Authors don't want to list every single component from jQuery UI in the
import directive, and they don't want the jQuery UI logic to be in a
different global object. They want to be able to import jQuery UI and have
it transitively import jQuery thus providing $ in the window in addition to
all the widgets and their API. ex. body.appendChild(new
JQUIPanel()).showPanel().

Note also that using a different global produces craziness like Array being
different or the prototypes of nodes being different. You definitely don't
want that for the same origin or CORS use case.


 Fortunately, there is already a boundary that we built that might be just
 the right fit for this problem: the shadow DOM boundary. A while back, we
 had lunch with Mozilla security researchers who were interested in
 harnessing the power of Shadow DOM, and Elliott (cc'd) came up with a
 pretty nifty proposal called the DOMWorker. I nagged him and he is
 hopefully going to post it on public-webapps. I am pretty sure that his
 proposal can address your use case and not cripple the rest of the spec in
 the process.


 Assuming you’re referring to
 https://docs.google.com/document/d/1V7ci1-lBTY6AJxgN99aCMwjZKCjKv1v3y_7WLtcgM00/edit,
 the security model of our proposal is very similar.  All we’re doing is
 using a HTML-imported document instead of a worker to isolate the
 cross-origin component.

 Since we don’t want to run the cross-origin component on a separate
 thread, I don’t think worker is a good model for cross-origin components.


A DOMWorker doesn't run on another thread, see the Note in the introduction.

- E


Re: [webcomponents] Proposal for Cross Origin Use Case and Declarative Syntax

2013-11-12 Thread Brian Di Palma
I'm not sure I would want jQuery UI to pollute the window object with
$, with ES6 modules around the corner it seems like a step backwards
for imports to start polluting window objects with their libraries...

On Tue, Nov 12, 2013 at 9:01 PM, Elliott Sprehn espr...@gmail.com wrote:

 On Tue, Nov 12, 2013 at 12:45 AM, Ryosuke Niwa rn...@apple.com wrote:

 [...]

 Script in the import is executed in the context of the window that
 contains the importingdocument. So window.document refers to the main page
 document. This has two useful corollaries:

 functions defined in an import end up on window.
 you don't have to do anything crazy like append the import's script
 blocks to the main page. Again, script gets executed.

 What we’re proposing is to execute the script in the imported document so
 the only real argument is the point that “functions defined in an imported
 end up on window” (of the host document).

 I think that’s a bad thing.  We don’t want imported documents to start
 polluting global scope without the user explicitly importing them.  e.g.
 import X in Python doesn’t automatically import stuff inside the module
 into your global scope.  To do that, you explicitly say “import * from X”.
 Similarly, “using std” is discouraged in C++.

 I don’t think the argument that this is how external script and stylesheet
 fly either because the whole point of web components is about improving the
 modularity and reusability of the Web.


 What you're proposing breaks a primary use case of:

 link rel=import href=//apis.google.com/jquery-ui.html

 Authors don't want to list every single component from jQuery UI in the
 import directive, and they don't want the jQuery UI logic to be in a
 different global object. They want to be able to import jQuery UI and have
 it transitively import jQuery thus providing $ in the window in addition to
 all the widgets and their API. ex. body.appendChild(new
 JQUIPanel()).showPanel().

 Note also that using a different global produces craziness like Array being
 different or the prototypes of nodes being different. You definitely don't
 want that for the same origin or CORS use case.


 Fortunately, there is already a boundary that we built that might be just
 the right fit for this problem: the shadow DOM boundary. A while back, we
 had lunch with Mozilla security researchers who were interested in
 harnessing the power of Shadow DOM, and Elliott (cc'd) came up with a pretty
 nifty proposal called the DOMWorker. I nagged him and he is hopefully going
 to post it on public-webapps. I am pretty sure that his proposal can address
 your use case and not cripple the rest of the spec in the process.


 Assuming you’re referring to
 https://docs.google.com/document/d/1V7ci1-lBTY6AJxgN99aCMwjZKCjKv1v3y_7WLtcgM00/edit,
 the security model of our proposal is very similar.  All we’re doing is
 using a HTML-imported document instead of a worker to isolate the
 cross-origin component.

 Since we don’t want to run the cross-origin component on a separate
 thread, I don’t think worker is a good model for cross-origin components.


 A DOMWorker doesn't run on another thread, see the Note in the introduction.

 - E




Re: [webcomponents] Proposal for Cross Origin Use Case and Declarative Syntax

2013-11-12 Thread Ryosuke Niwa
On Nov 13, 2013, at 7:21 AM, Brian Di Palma off...@gmail.com wrote:

 I'm not sure I would want jQuery UI to pollute the window object with
 $, with ES6 modules around the corner it seems like a step backwards
 for imports to start polluting window objects with their libraries…

Indeed!

 On Tue, Nov 12, 2013 at 9:01 PM, Elliott Sprehn espr...@gmail.com wrote:
 
 On Tue, Nov 12, 2013 at 12:45 AM, Ryosuke Niwa rn...@apple.com wrote:
 
 [...]
 
 Script in the import is executed in the context of the window that
 contains the importingdocument. So window.document refers to the main page
 document. This has two useful corollaries:
 
 functions defined in an import end up on window.
 you don't have to do anything crazy like append the import's script
 blocks to the main page. Again, script gets executed.
 
 What we’re proposing is to execute the script in the imported document so
 the only real argument is the point that “functions defined in an imported
 end up on window” (of the host document).
 
 I think that’s a bad thing.  We don’t want imported documents to start
 polluting global scope without the user explicitly importing them.  e.g.
 import X in Python doesn’t automatically import stuff inside the module
 into your global scope.  To do that, you explicitly say “import * from X”.
 Similarly, “using std” is discouraged in C++.
 
 I don’t think the argument that this is how external script and stylesheet
 fly either because the whole point of web components is about improving the
 modularity and reusability of the Web.
 
 
 What you're proposing breaks a primary use case of:
 
 link rel=import href=//apis.google.com/jquery-ui.html
 
 Authors don't want to list every single component from jQuery UI in the
 import directive, and they don't want the jQuery UI logic to be in a
 different global object. They want to be able to import jQuery UI and have
 it transitively import jQuery thus providing $ in the window in addition to
 all the widgets and their API. ex. body.appendChild(new
 JQUIPanel()).showPanel().

I think we can support something like import=* that'll import all global 
symbols defined in the component into your namespace.

 Note also that using a different global produces craziness like Array being
 different or the prototypes of nodes being different. You definitely don't
 want that for the same origin or CORS use case.

I'm not sure.  If you have a funky library that ends up polluting Array's 
prototype for example, then you don't want that pollution to get into other 
library you're using on the same page.

The fact each library has its own clean slate to play with is a good thing.

 Fortunately, there is already a boundary that we built that might be just
 the right fit for this problem: the shadow DOM boundary. A while back, we
 had lunch with Mozilla security researchers who were interested in
 harnessing the power of Shadow DOM, and Elliott (cc'd) came up with a pretty
 nifty proposal called the DOMWorker. I nagged him and he is hopefully going
 to post it on public-webapps. I am pretty sure that his proposal can address
 your use case and not cripple the rest of the spec in the process.
 
 
 Assuming you’re referring to
 https://docs.google.com/document/d/1V7ci1-lBTY6AJxgN99aCMwjZKCjKv1v3y_7WLtcgM00/edit,
 the security model of our proposal is very similar.  All we’re doing is
 using a HTML-imported document instead of a worker to isolate the
 cross-origin component.
 
 Since we don’t want to run the cross-origin component on a separate
 thread, I don’t think worker is a good model for cross-origin components.
 
 A DOMWorker doesn't run on another thread, see the Note in the introduction.

I know that.  What I'm saying is that it completely defeats the point of using 
worker.  To quote Maciej:

 Other reasons the worker proposal seems weaker than a separate Window-like 
 global object holding the import document:
 
 (1) The proposal says:
 
 Note: No asynchronous guarantees are made for DOMWorker, specifically a busy 
 loop inside the worker may hang the main page completely unlike a regular 
 worker. Developers should assume that a DOMWorker is time sharing the same 
 event loops as the owning document.
 
 Doesn't this completely defeat any benefit to using a Worker instead of, say, 
 a Window-like global object with its own document?
 
 (2) Using a worker (which therefore has no source document) makes it awkward 
 to use templates, if you wanted to.
 
 (3) The custom element binding and setup code still runs in the host 
 document, so this doesn't create a strong security boundary because you'd 
 still need to embed external JS and run it in your own security context to 
 set up the custom element. At best this can protect the component from the 
 embedder, but not vice versa.


- R. Niwa



Re: [webcomponents] Proposal for Cross Origin Use Case and Declarative Syntax

2013-11-12 Thread Scott Miles
 pollute the window object with $, with ES6 modules around the corner

The $ was just an example, the import could also happily define one or more
modules. This concept allows us to decouple scoping from imports.

Now, the import is only a vehicle, but it advances the state of the art by
also delivering canonical HTML and CSS (instead of requiring JavaScript to
load or encode additional resources). We right away have an efficient
method for draining some of the existing resource management swamp.

From there I can see paths to supporting opt-in isolation models, either
directly, or by delegating to an agent like DOMWorker.


On Tue, Nov 12, 2013 at 3:21 PM, Brian Di Palma off...@gmail.com wrote:

 I'm not sure I would want jQuery UI to pollute the window object with
 $, with ES6 modules around the corner it seems like a step backwards
 for imports to start polluting window objects with their libraries...

 On Tue, Nov 12, 2013 at 9:01 PM, Elliott Sprehn espr...@gmail.com wrote:
 
  On Tue, Nov 12, 2013 at 12:45 AM, Ryosuke Niwa rn...@apple.com wrote:
 
  [...]
 
  Script in the import is executed in the context of the window that
  contains the importingdocument. So window.document refers to the main
 page
  document. This has two useful corollaries:
 
  functions defined in an import end up on window.
  you don't have to do anything crazy like append the import's script
  blocks to the main page. Again, script gets executed.
 
  What we’re proposing is to execute the script in the imported document
 so
  the only real argument is the point that “functions defined in an
 imported
  end up on window” (of the host document).
 
  I think that’s a bad thing.  We don’t want imported documents to start
  polluting global scope without the user explicitly importing them.  e.g.
  import X in Python doesn’t automatically import stuff inside the
 module
  into your global scope.  To do that, you explicitly say “import * from
 X”.
  Similarly, “using std” is discouraged in C++.
 
  I don’t think the argument that this is how external script and
 stylesheet
  fly either because the whole point of web components is about improving
 the
  modularity and reusability of the Web.
 
 
  What you're proposing breaks a primary use case of:
 
  link rel=import href=//apis.google.com/jquery-ui.html
 
  Authors don't want to list every single component from jQuery UI in the
  import directive, and they don't want the jQuery UI logic to be in a
  different global object. They want to be able to import jQuery UI and
 have
  it transitively import jQuery thus providing $ in the window in addition
 to
  all the widgets and their API. ex. body.appendChild(new
  JQUIPanel()).showPanel().
 
  Note also that using a different global produces craziness like Array
 being
  different or the prototypes of nodes being different. You definitely
 don't
  want that for the same origin or CORS use case.
 
 
  Fortunately, there is already a boundary that we built that might be
 just
  the right fit for this problem: the shadow DOM boundary. A while back,
 we
  had lunch with Mozilla security researchers who were interested in
  harnessing the power of Shadow DOM, and Elliott (cc'd) came up with a
 pretty
  nifty proposal called the DOMWorker. I nagged him and he is hopefully
 going
  to post it on public-webapps. I am pretty sure that his proposal can
 address
  your use case and not cripple the rest of the spec in the process.
 
 
  Assuming you’re referring to
 
 https://docs.google.com/document/d/1V7ci1-lBTY6AJxgN99aCMwjZKCjKv1v3y_7WLtcgM00/edit
 ,
  the security model of our proposal is very similar.  All we’re doing is
  using a HTML-imported document instead of a worker to isolate the
  cross-origin component.
 
  Since we don’t want to run the cross-origin component on a separate
  thread, I don’t think worker is a good model for cross-origin
 components.
 
 
  A DOMWorker doesn't run on another thread, see the Note in the
 introduction.
 
  - E
 




Re: [webcomponents] Proposal for Cross Origin Use Case and Declarative Syntax

2013-11-11 Thread Ryosuke Niwa
On Nov 11, 2013, at 3:56 PM, Adam Barth w...@adambarth.com wrote:

 Can you help me understand what security properties your proposal
 achieves and how it achieves them?  I spent some time thinking about
 this problem a couple of years ago when this issue was discussed in
 depth, but I couldn't come up with a design that was simultaneously
 useful and secure.
 
 For example, your proposal seems to have the vulnerability described below:
 
 == Trusted container document ==
 
 link rel=import
 href=https://untrusted.org/untrusted-components.html;
 importcomponents=name-card
 body
 name-card /name-card
 
 == untrusted-components.html ==
 
 template defines=name-card interface=NameCardElement
 Name: {{name}}brEmail:{{email}}
 /template
 script
 NameCardElement.prototype.created = function (shadowRoot) {
  var victim = shadowRoot.ownerDocument;
  var script = victim.createElement(script);
  script.textContent = alert(/hacked/);;
  victim.body.appendChild(script);
 };
 /script
 
 Maybe I'm not understanding your proposal correct?  If this issue is
 indeed a vulnerability with your proposal, I have no doubt that you
 can modify your proposal to patch this hole, but iterating in that way
 isn't likely to lead to a secure design.

The owner document of the shadow root in that case will be that of the 
component; i.e. https://untrusted.org/untrusted-components.html in this case.

In other words, we’re inserting a security boundary between the host element 
and the shadow root.  The shadow root in this case is a funky node object in 
that it has its host element in an entirely different document.

- R. Niwa




Re: [webcomponents] Proposal for Cross Origin Use Case and Declarative Syntax

2013-11-11 Thread Adam Barth
On Mon, Nov 11, 2013 at 12:57 AM, Ryosuke Niwa rn...@apple.com wrote:
 On Nov 11, 2013, at 3:56 PM, Adam Barth w...@adambarth.com wrote:
 Can you help me understand what security properties your proposal
 achieves and how it achieves them?  I spent some time thinking about
 this problem a couple of years ago when this issue was discussed in
 depth, but I couldn't come up with a design that was simultaneously
 useful and secure.

 For example, your proposal seems to have the vulnerability described below:

 == Trusted container document ==

 link rel=import
 href=https://untrusted.org/untrusted-components.html;
 importcomponents=name-card
 body
 name-card /name-card

 == untrusted-components.html ==

 template defines=name-card interface=NameCardElement
 Name: {{name}}brEmail:{{email}}
 /template
 script
 NameCardElement.prototype.created = function (shadowRoot) {
  var victim = shadowRoot.ownerDocument;
  var script = victim.createElement(script);
  script.textContent = alert(/hacked/);;
  victim.body.appendChild(script);
 };
 /script

 Maybe I'm not understanding your proposal correct?  If this issue is
 indeed a vulnerability with your proposal, I have no doubt that you
 can modify your proposal to patch this hole, but iterating in that way
 isn't likely to lead to a secure design.

 The owner document of the shadow root in that case will be that of the 
 component; i.e. https://untrusted.org/untrusted-components.html in this case.

 In other words, we’re inserting a security boundary between the host element 
 and the shadow root.  The shadow root in this case is a funky node object in 
 that it has its host element in an entirely different document.

Was that written somewhere in your proposal and I missed it?

Adam



Re: [webcomponents] Proposal for Cross Origin Use Case and Declarative Syntax

2013-11-11 Thread Ryosuke Niwa

On Nov 11, 2013, at 5:33 PM, Ryosuke Niwa rn...@apple.com wrote:

 On Nov 11, 2013, at 5:13 PM, Adam Barth w...@adambarth.com wrote:
 On Mon, Nov 11, 2013 at 12:57 AM, Ryosuke Niwa rn...@apple.com wrote:
 On Nov 11, 2013, at 3:56 PM, Adam Barth w...@adambarth.com wrote:
 Can you help me understand what security properties your proposal
 achieves and how it achieves them?  I spent some time thinking about
 this problem a couple of years ago when this issue was discussed in
 depth, but I couldn't come up with a design that was simultaneously
 useful and secure.
 
 For example, your proposal seems to have the vulnerability described below:
 
 == Trusted container document ==
 
 link rel=import
 href=https://untrusted.org/untrusted-components.html;
 importcomponents=name-card
 body
 name-card /name-card
 
 == untrusted-components.html ==
 
 template defines=name-card interface=NameCardElement
 Name: {{name}}brEmail:{{email}}
 /template
 script
 NameCardElement.prototype.created = function (shadowRoot) {
 var victim = shadowRoot.ownerDocument;
 var script = victim.createElement(script);
 script.textContent = alert(/hacked/);;
 victim.body.appendChild(script);
 };
 /script
 
 Maybe I'm not understanding your proposal correct?  If this issue is
 indeed a vulnerability with your proposal, I have no doubt that you
 can modify your proposal to patch this hole, but iterating in that way
 isn't likely to lead to a secure design.
 
 The owner document of the shadow root in that case will be that of the 
 component; i.e. https://untrusted.org/untrusted-components.html in this 
 case.
 
 In other words, we’re inserting a security boundary between the host 
 element and the shadow root.  The shadow root in this case is a funky node 
 object in that it has its host element in an entirely different document.
 
 Was that written somewhere in your proposal and I missed it?
 
 I intended to state this in point 6 but now I realize it wasn’t entirely 
 clear from the way I phrase it so let me elaborate a little more on this 
 point.
 
 When a cross-origin custom element is instantiated, the browser creates the 
 JS wrapper for the custom element in the context of the imported document.  
 It then creates a shadow root inside the imported document, attaches it to 
 the host element, and calls createdCallback with the shadow root.
 
 The custom element JS object is only visible inside the imported document.  
 It’s HTMLUnknownElement in the context of the host document although we’re 
 open to creating a proxy/fake element subclass which is not visible in the 
 global scope and identical to HTMLKnownElement in its prototype chain in the 
 host document as well.

Of course, the imported document will have a different script context (i.e. 
global object) than the host document.

(Anne: Thank you for pointing this out).

- R. Niwa



Re: [webcomponents] Proposal for Cross Origin Use Case and Declarative Syntax

2013-11-11 Thread Elliott Sprehn
On Mon, Nov 11, 2013 at 1:33 AM, Ryosuke Niwa rn...@apple.com wrote:

 [...] we’re open to creating a proxy/fake element subclass which is not
 visible in the global scope and identical to HTMLKnownElement in its
 prototype chain in the host document as well.


Can you clarify why it can't be visible in the global scope? Why can't I do
document.body.appendChild(new FBLikeButton()) or
document.body.firstElementChild instanceof FBLikeButton?

-E


Re: [webcomponents] Proposal for Cross Origin Use Case and Declarative Syntax

2013-11-11 Thread Ryosuke Niwa
On Nov 12, 2013, at 6:22 AM, Elliott Sprehn espr...@gmail.com wrote:
 
 On Mon, Nov 11, 2013 at 1:33 AM, Ryosuke Niwa rn...@apple.com wrote:
 [...] we’re open to creating a proxy/fake element subclass which is not 
 visible in the global scope and identical to HTMLKnownElement in its 
 prototype chain in the host document as well.
 
 
 Can you clarify why it can't be visible in the global scope?

Allowing the imported document to define arbitrary interface to the global 
scope of the host document will be a security vulnerability unless the host 
document explicitly lists the name of interfaces, or there is a strict mapping 
between tag names and interface names.

 Why can't I do document.body.appendChild(new FBLikeButton()) or 
 document.body.firstElementChild instanceof FBLikeButton?

One way to accomplish this will be adding yet another attribute that imports 
the list of interfaces;
e.g. link ref=import importelements=“like-button” 
importinterfaces=“FBLikeButton”
or defining a map between tag names and interface names (e.g. tag-name  
TagName), or exporting it on the link element. e.g. 
likeButtonLinkElement.importedcomponents.FBLikeButton.

- R. Niwa



Re: [webcomponents] Proposal for Cross Origin Use Case and Declarative Syntax

2013-11-11 Thread Dimitri Glazkov
On Sun, Nov 10, 2013 at 6:49 PM, Arthur Barstow art.bars...@nokia.comwrote:

 Hi Dimitri, Dominic,

 Ryosuke is here in Shezhen at WebApps' f2f meeting. We would like to have
 one or both of you join us (via voice conference) on Tuesday morning to
 talk about Web Components and his comments below.

 Please look at the agenda page and let us know your availability for the
 one of the open slots before lunch (all times are local to Shenzhen):

 http://www.w3.org/wiki/Webapps/November2013Meeting#
 Agenda_Tuesday_November_12


I dropped something at 9:30am. I think that's 5:30pm Mountain View and
10:30am Tokyo, right?



 -Thanks, ArtB


 On 11/9/13 3:24 AM, ext Ryosuke Niwa wrote:

 Hi all,

 We have been discussing cross-orign use case and declarative syntax of
 web components internally at Apple, and here are our straw man proposal to
 amend the existing Web Components specifications to support it.

 *1. Modify HTML Imports to run scripts in the imported document itself*

 This allows the importee and the importer to not share the same script
 context, etc…


This could be an option and shouldn’t be the default. By running scripts in
a different context, we are ejecting the primary use case of enabling
frameworks/libraries to better manage their assets and dependencies (aka
the Bootstrap use case).

Rob Dodson’s article has a nice progression explaining the use case:
http://robdodson.me/blog/2013/08/20/exploring-html-imports/

Also, check out newly minted Eric Bidelman's article on imports (especially
the use cases section at the bottom):
http://www.html5rocks.com/en/tutorials/webcomponents/imports/

*Re: Custom Elements LC*, this is an issue to handle in HTML Imports
specification, not related to Custom Elements.



 *2. Add “importcomponents content attribute on link element*

 It defines the list of custom element tag names to be imported from the
 imported HTML document.
 e.g. link rel=import href=~ importcomponents=tag-1 tag-2 will
 export custom elements of tag names tag-1 and tag-2 from ~. Any name
 that didn't have a definition in the import document is ignored (i.e. if
 tag-2 was not defined in ~, it would be skipped but tag-1 will be still
 imported).

 This mechanism prevents the imported document from defining arbitrary
 components in the host document.


*Re: Custom Elements LC*, this should be handled in HTML Imports
specification. HTML Imports can rely on Custom Elements specification. Any
additional hooks that could be needed to facilitate this feature could be
added in Custom Elements Level 2 specification.



 *3. Support static (write-once) binding of a HTML template*

 e.g.
 template id=cardTemplateName: {{name}}brEmail:{{email}}/template
 script
 document.body.appendChild(cardTemplate.instantiate({name: Ryosuke
 Niwa, email:rn...@webkit.org mailto:rn...@webkit.org}));
 /script


This seems very similar to the Rafael Weinstein's MDV work. You guys should
collaborate :)

*Re: Custom Elements LC*, this is unrelated to specification.


 *4. Add “interface content attribute to template element*

 This content attribute specifies the name of the JavaScript constructor
 function to be created in the global scope. The UA creates one and will be
 used to instantiate a given custom element. The author can then setup the
 prototype chain as needed:

 template defines=name-card interface=NameCardElement
 Name: {{name}}brEmail:{{email}}
 /template
 script
 NameCardElement.prototype.name = function () {...}
 NameCardElement.prototype.email = function () {...}
 /script

 This is similar to doing:
 var NameCardElement = document.register(’name-card');


This is another take on the declarative custom elements (a variant of [1]).
This particular approach has four problems that the WG was able to resolve
(at least the first three) in previous iterations:

1) It is not friendly to ES6 classes. In fact, you can't use class syntax
and this syntax together.

2) It couples templates, shadow DOM, and custom elements in a way that's
highly opinionated and inflexible. Throughout this year, we've tried many
various ways to get this right, and failed [2]. I highly recommend that we
avoid putting this into a specification now. Instead, we should let the
best practices evolve and build on the cowpaths.

3) The approach pollutes global name space with constructors. This had been
voiced many times as unacceptable by developers.

4) How does build a custom element that uses name-card as its base
element? What about div or any other HTML element?

The last one remains to be the hardest. The tortured inheritance support is
what killed element in the first place. We can't ignore the inheritance,
since it is clearly present, in both DOM and JS. If we attempt to punt on
supporting it, our decisions cut off the opportunities to evolve this right
in the future, and will likely leave us with boogers like multiple syntaxes
for inheritance vs. non-inheritance use cases.

I recommend studying the work the WG had already done here 

RE: [webcomponents] Proposal for Cross Origin Use Case and Declarative Syntax

2013-11-11 Thread Art.Barstow
Dimitri - yes, timeanddate.com agrees: 09:30 Shenzhen = 10:30 Tokyo = 17:30 San 
Francisco. The pin will be 9274# and we will use the #webapps channel.

-TTYS, ArtB

Sent from my Windows Phone

From: ext Dimitri Glazkovmailto:dglaz...@chromium.org
Sent: ‎11/‎12/‎2013 8:13 AM
To: Barstow Art (Nokia-CIC/Boston)mailto:art.bars...@nokia.com
Cc: ext Ryosuke Niwamailto:rn...@apple.com; Dominic 
Cooneymailto:domin...@chromium.org; public-webapps@w3.org 
WGmailto:public-webapps@w3.org; Elliott Sprehnmailto:espr...@gmail.com
Subject: Re: [webcomponents] Proposal for Cross Origin Use Case and Declarative 
Syntax


On Sun, Nov 10, 2013 at 6:49 PM, Arthur Barstow 
art.bars...@nokia.commailto:art.bars...@nokia.com wrote:
Hi Dimitri, Dominic,

Ryosuke is here in Shezhen at WebApps' f2f meeting. We would like to have one 
or both of you join us (via voice conference) on Tuesday morning to talk about 
Web Components and his comments below.

Please look at the agenda page and let us know your availability for the one of 
the open slots before lunch (all times are local to Shenzhen):

http://www.w3.org/wiki/Webapps/November2013Meeting#Agenda_Tuesday_November_12

I dropped something at 9:30am. I think that's 5:30pm Mountain View and 10:30am 
Tokyo, right?


-Thanks, ArtB


On 11/9/13 3:24 AM, ext Ryosuke Niwa wrote:
Hi all,

We have been discussing cross-orign use case and declarative syntax of web 
components internally at Apple, and here are our straw man proposal to amend 
the existing Web Components specifications to support it.

*1. Modify HTML Imports to run scripts in the imported document itself*

This allows the importee and the importer to not share the same script context, 
etc…


This could be an option and shouldn’t be the default. By running scripts in a 
different context, we are ejecting the primary use case of enabling 
frameworks/libraries to better manage their assets and dependencies (aka the 
Bootstrap use case).

Rob Dodson’s article has a nice progression explaining the use case: 
http://robdodson.me/blog/2013/08/20/exploring-html-imports/

Also, check out newly minted Eric Bidelman's article on imports (especially the 
use cases section at the bottom): 
http://www.html5rocks.com/en/tutorials/webcomponents/imports/

Re: Custom Elements LC, this is an issue to handle in HTML Imports 
specification, not related to Custom Elements.


*2. Add “importcomponents content attribute on link element*

It defines the list of custom element tag names to be imported from the 
imported HTML document.
e.g. link rel=import href=~ importcomponents=tag-1 tag-2 will export 
custom elements of tag names tag-1 and tag-2 from ~. Any name that didn't 
have a definition in the import document is ignored (i.e. if tag-2 was not 
defined in ~, it would be skipped but tag-1 will be still imported).

This mechanism prevents the imported document from defining arbitrary 
components in the host document.

Re: Custom Elements LC, this should be handled in HTML Imports specification. 
HTML Imports can rely on Custom Elements specification. Any additional hooks 
that could be needed to facilitate this feature could be added in Custom 
Elements Level 2 specification.


*3. Support static (write-once) binding of a HTML template*

e.g.
template id=cardTemplateName: {{name}}brEmail:{{email}}/template
script
document.body.appendChild(cardTemplate.instantiate({name: Ryosuke Niwa, 
email:rn...@webkit.orgmailto:rn...@webkit.org 
mailto:rn...@webkit.orgmailto:rn...@webkit.org}));
/script

This seems very similar to the Rafael Weinstein's MDV work. You guys should 
collaborate :)

Re: Custom Elements LC, this is unrelated to specification.

*4. Add “interface content attribute to template element*

This content attribute specifies the name of the JavaScript constructor 
function to be created in the global scope. The UA creates one and will be used 
to instantiate a given custom element. The author can then setup the prototype 
chain as needed:

template defines=name-card interface=NameCardElement
Name: {{name}}brEmail:{{email}}
/template
script
NameCardElement.prototype.namehttp://NameCardElement.prototype.name = 
function () {...}
NameCardElement.prototype.email = function () {...}
/script

This is similar to doing:
var NameCardElement = document.register(’name-card');

This is another take on the declarative custom elements (a variant of [1]). 
This particular approach has four problems that the WG was able to resolve (at 
least the first three) in previous iterations:

1) It is not friendly to ES6 classes. In fact, you can't use class syntax and 
this syntax together.

2) It couples templates, shadow DOM, and custom elements in a way that's highly 
opinionated and inflexible. Throughout this year, we've tried many various ways 
to get this right, and failed [2]. I highly recommend that we avoid putting 
this into a specification now. Instead, we should let the best practices evolve 
and build on the cowpaths

Re: [webcomponents] Proposal for Cross Origin Use Case and Declarative Syntax

2013-11-10 Thread Arthur Barstow

Hi Dimitri, Dominic,

Ryosuke is here in Shezhen at WebApps' f2f meeting. We would like to 
have one or both of you join us (via voice conference) on Tuesday 
morning to talk about Web Components and his comments below.


Please look at the agenda page and let us know your availability for the 
one of the open slots before lunch (all times are local to Shenzhen):


http://www.w3.org/wiki/Webapps/November2013Meeting#Agenda_Tuesday_November_12

-Thanks, ArtB

On 11/9/13 3:24 AM, ext Ryosuke Niwa wrote:

Hi all,

We have been discussing cross-orign use case and declarative syntax of 
web components internally at Apple, and here are our straw man 
proposal to amend the existing Web Components specifications to 
support it.


*1. Modify HTML Imports to run scripts in the imported document itself*
This allows the importee and the importer to not share the same script 
context, etc…


*2. Add “importcomponents content attribute on link element*
It defines the list of custom element tag names to be imported from 
the imported HTML document.
e.g. link rel=import href=~ importcomponents=tag-1 tag-2 will 
export custom elements of tag names tag-1 and tag-2 from ~. Any 
name that didn't have a definition in the import document is ignored 
(i.e. if tag-2 was not defined in ~, it would be skipped but tag-1 
will be still imported).


This mechanism prevents the imported document from defining arbitrary 
components in the host document.


*3. Support static (write-once) binding of a HTML template*
e.g.
template id=cardTemplateName: {{name}}brEmail:{{email}}/template
script
document.body.appendChild(cardTemplate.instantiate({name: Ryosuke 
Niwa, email:rn...@webkit.org mailto:rn...@webkit.org}));

/script

*4. Add “interface content attribute to template element*
This content attribute specifies the name of the JavaScript 
constructor function to be created in the global scope. The UA creates 
one and will be used to instantiate a given custom element. The author 
can then setup the prototype chain as needed:


template defines=name-card interface=NameCardElement
Name: {{name}}brEmail:{{email}}
/template
script
NameCardElement.prototype.name = function () {...}
NameCardElement.prototype.email = function () {...}
/script

This is similar to doing:
var NameCardElement = document.register(’name-card');

*5. Add defines content attribute on HTML template element to define 
a custom element*
This new attribute defines a custom element of the given name for the 
template content.
e.g. template defines=nestedDivdivdiv/div/div/template 
will let you use nestedDiv/nestedDiv


We didn’t think having a separate custom element was useful because we 
couldn’t think of a use case where you wanted to define a custom 
element declaratively and not use template by default, and having to 
associate the first template element with the custom element seemed 
unnecessary complexity.


*5.1. When a custom element is instantiated, automatically instantiate 
template inside a shadow root after statically binding the template 
with dataset*

This allows statically declaring arguments to a component.
e.g.
template defines=name-cardName: {{name}}brEmail:{{email}}/template
name-card data-name=Ryosuke Niwa data-email=rn...@webkit.org 
mailto:rn...@webkit.org”


*5.2. When a new custom element object is constructed, created 
callback is called with a shadow root*
Unfortunately, we can't let the author define a constructor because 
the element hadn't been properly initialized with the right JS wrapper 
at the time of its construction. So just like we can't do new 
HTMLTitleElement, we're not going to let the author do an interesting 
things inside a custom element's constructor. Instead, we're going to 
call created function on its prototype chain:


template defines=name-card interface=NameCardElement
Name: {{name}}brEmail:{{email}}
/template
script
NameCardElement.prototype.name = function () {...}
NameCardElement.prototype.email = function () {...}
NameCardElement.prototype.created = function (shadowRoot) {
... // Initialize the shadowRoot here.
}
/script

This is similar to the way document.register works in that 
document.register creates a constructor automatically.


*6. The cross-origin component does not have access to the shadow host 
element, and the host document doesn’t have access to the element object.*
When member functions of the element is called, “this” object will be 
undefined. This is necessary because exposing the object to a 
cross-origin content will result in tricky security issues, forcing us 
to have proxy objects, etc…


Inside the document that imported a component, the element doesn’t use 
the prototype defined by the component as that exposes JS objects 
cross-origin. e.g. even if LikeButtonElement was defined in 
facebook.com/~/like-button.html 
http://facebook.com/%7E/like-button.html, the document that uses 
this component wouldn’t see the prototype or the constructor. It’ll be 
HTMLUnknownElement. (We could create a 

Re: [webcomponents] Proposal for Cross Origin Use Case and Declarative Syntax

2013-11-10 Thread Adam Barth
Hi Ryosuke,

Can you help me understand what security properties your proposal
achieves and how it achieves them?  I spent some time thinking about
this problem a couple of years ago when this issue was discussed in
depth, but I couldn't come up with a design that was simultaneously
useful and secure.

For example, your proposal seems to have the vulnerability described below:

== Trusted container document ==

link rel=import
href=https://untrusted.org/untrusted-components.html;
importcomponents=name-card
body
name-card /name-card

== untrusted-components.html ==

template defines=name-card interface=NameCardElement
Name: {{name}}brEmail:{{email}}
/template
script
NameCardElement.prototype.created = function (shadowRoot) {
  var victim = shadowRoot.ownerDocument;
  var script = victim.createElement(script);
  script.textContent = alert(/hacked/);;
  victim.body.appendChild(script);
};
/script

Maybe I'm not understanding your proposal correct?  If this issue is
indeed a vulnerability with your proposal, I have no doubt that you
can modify your proposal to patch this hole, but iterating in that way
isn't likely to lead to a secure design.

Thanks,
Adam


On Fri, Nov 8, 2013 at 11:24 AM, Ryosuke Niwa rn...@apple.com wrote:
 Hi all,

 We have been discussing cross-orign use case and declarative syntax of web
 components internally at Apple, and here are our straw man proposal to amend
 the existing Web Components specifications to support it.

 1. Modify HTML Imports to run scripts in the imported document itself
 This allows the importee and the importer to not share the same script
 context, etc…

 2. Add “importcomponents content attribute on link element
 It defines the list of custom element tag names to be imported from the
 imported HTML document.
 e.g. link rel=import href=~ importcomponents=tag-1 tag-2 will export
 custom elements of tag names tag-1 and tag-2 from ~.  Any name that
 didn't have a definition in the import document is ignored (i.e. if tag-2
 was not defined in ~, it would be skipped but tag-1 will be still
 imported).

 This mechanism prevents the imported document from defining arbitrary
 components in the host document.

 3. Support static (write-once) binding of a HTML template
 e.g.
 template id=cardTemplateName: {{name}}brEmail:{{email}}/template
 script
 document.body.appendChild(cardTemplate.instantiate({name: Ryosuke Niwa,
 email:rn...@webkit.org}));
 /script

 4. Add “interface content attribute to template element
 This content attribute specifies the name of the JavaScript constructor
 function to be created in the global scope. The UA creates one and will be
 used to instantiate a given custom element.  The author can then setup the
 prototype chain as needed:

 template defines=name-card interface=NameCardElement
 Name: {{name}}brEmail:{{email}}
 /template
 script
 NameCardElement.prototype.name = function () {...}
 NameCardElement.prototype.email = function () {...}
 /script

 This is similar to doing:
 var NameCardElement = document.register(’name-card');

 5. Add defines content attribute on HTML template element to define a
 custom element
 This new attribute defines a custom element of the given name for the
 template content.
 e.g. template defines=nestedDivdivdiv/div/div/template will
 let you use nestedDiv/nestedDiv

 We didn’t think having a separate custom element was useful because we
 couldn’t think of a use case where you wanted to define a custom element
 declaratively and not use template by default, and having to associate the
 first template element with the custom element seemed unnecessary
 complexity.

 5.1. When a custom element is instantiated, automatically instantiate
 template inside a shadow root after statically binding the template with
 dataset
 This allows statically declaring arguments to a component.
 e.g.
 template defines=name-cardName: {{name}}brEmail:{{email}}/template
 name-card data-name=Ryosuke Niwa data-email=rn...@webkit.org”

 5.2. When a new custom element object is constructed, created callback is
 called with a shadow root
 Unfortunately, we can't let the author define a constructor because the
 element hadn't been properly initialized with the right JS wrapper at the
 time of its construction.  So just like we can't do new HTMLTitleElement,
 we're not going to let the author do an interesting things inside a custom
 element's constructor.  Instead, we're going to call created function on
 its prototype chain:

 template defines=name-card interface=NameCardElement
 Name: {{name}}brEmail:{{email}}
 /template
 script
 NameCardElement.prototype.name = function () {...}
 NameCardElement.prototype.email = function () {...}
 NameCardElement.prototype.created = function (shadowRoot) {
 ... // Initialize the shadowRoot here.
 }
 /script

 This is similar to the way document.register works in that document.register
 creates a constructor automatically.

 6. The cross-origin component does not have access to the shadow host