Re: CSP 1.1 DOM design
On Sun, Nov 4, 2012 at 9:58 PM, Alex Russell slightly...@google.com wrote: Looking at Section 3.4 of the CSP 1.1 draft [1], I'm noticing that the IDL specified feels very, very strange to use from the JS perspective. Thanks for taking a look! This is great feedback. For instance, the name document.SecurityPolicy would indicate to a mere JS hacker like me that the SecurityPolicy is a class from which instances will be created. Instead, it's an instance of the SecurityPolicy interface. A more idiomatic name might be document.policy, document.csp, or document.securityPolicy as leading-caps tend to be reserved for classes, not instances. Adam, do you remember why we ran with 'SecurityPolicy' rather than 'securityPolicy'? I know we discussed it, but I can only find the comment resulting from that discussion ( https://bugs.webkit.org/show_bug.cgi?id=91707#c5). Similarly, it's not possible (AFAICT) to new-up an instance of SecurityPolicy and no API provided for parsing a policy to understand how it would react. That's an interesting suggestion. What's the use-case you see for providing a mechanism for parsing/examining a policy? The only thing I can come up with off the top of my head is the tool we briefly chatted about that would help developers understand the impact of a policy. :) Lastly, there's no serialization method provided. A toString() implementation might work well. What would the string representation of the object look like? Just the original policy? One complication is that the page's active policy might be created by the union of several policies (one sent per HTTP, one in a meta tag, etc). Would we want to retain that representation in a string version? readonly attribute DOMString[] reportURIs; We decided at TPAC to remove the reportURIs getter unless someone has a really good use-case for it. One open issue: I'm not sure If allowsEval, allowsInlineScript, and allowsInlineStyle should just be boolean getters or if they should stay methods. I like the idea of converting these `allowEval()`-style calls to read-only booleans. Perhaps 'isActive' as well. Also, it's unclear if the current document's policy should simply be a locked-down instance of a SecurityPolicy class that has accessors for each of the policy items (script-src, object-src, style-src, img-src, media-src, frame-src, font-src, connect-src). I think that's more or less what the current interface does. (e.g. `document.SecurityPolicy.allowsFontFrom('xxx')` is an accessor for the effective permissions granted via the 'font-src' directive). Would you prefer more direct access to the policy? We'd shied away from that on the assumption that this interface required less knowledge of CSP in order to usefully include on a page. Should we revisit that question? Thanks again! -- Mike West mk...@google.com, Developer Advocate Google Germany GmbH, Dienerstrasse 12, 80331 München, Germany Google+: https://mkw.st/+, Twitter: @mikewest, Cell: +49 162 10 255 91
Re: CSP 1.1 DOM design
On Mon, Nov 5, 2012 at 10:27 AM, Mike West mk...@google.com wrote: On Sun, Nov 4, 2012 at 9:58 PM, Alex Russell slightly...@google.com wrote: readonly attribute DOMString[] reportURIs; We decided at TPAC to remove the reportURIs getter unless someone has a really good use-case for it. If you bring it back in or have another member with the term URI, please use url instead. That's what we try to align the platform towards and most developer-facing APIs already use (e.g. input type=url, CSS url()). -- http://annevankesteren.nl/
Re: CSP 1.1 DOM design
Inline. On Mon, Nov 5, 2012 at 9:27 AM, Mike West mk...@google.com wrote: On Sun, Nov 4, 2012 at 9:58 PM, Alex Russell slightly...@google.comwrote: Looking at Section 3.4 of the CSP 1.1 draft [1], I'm noticing that the IDL specified feels very, very strange to use from the JS perspective. Thanks for taking a look! This is great feedback. For instance, the name document.SecurityPolicy would indicate to a mere JS hacker like me that the SecurityPolicy is a class from which instances will be created. Instead, it's an instance of the SecurityPolicy interface. A more idiomatic name might be document.policy, document.csp, or document.securityPolicy as leading-caps tend to be reserved for classes, not instances. Adam, do you remember why we ran with 'SecurityPolicy' rather than 'securityPolicy'? I know we discussed it, but I can only find the comment resulting from that discussion ( https://bugs.webkit.org/show_bug.cgi?id=91707#c5). Similarly, it's not possible (AFAICT) to new-up an instance of SecurityPolicy and no API provided for parsing a policy to understand how it would react. That's an interesting suggestion. What's the use-case you see for providing a mechanism for parsing/examining a policy? I'm hitting this in real time as I'm trying to write an extension that merges/displays policies. Long story short, I've got a default user policy that I'd like to apply to each page until/unless that page gives me a more locked-down policy. I'd also like to know what has been blocked in the page. The current API is balls for all of this. Luckily CSP parsing is easy. On the downside, matching and getting the rule application right isn't. There's already a parser/matcher in the implementation. Not exposing it is, on a more philosophical basis, simply bad design. The only thing I can come up with off the top of my head is the tool we briefly chatted about that would help developers understand the impact of a policy. :) That was going to be my other use-case: I want to build a tool that shows people how to construct policies well. But it's a minor point; the larger issue is that it's bad layering to say the browser does this but no, you can't have access to that parser/matching logic. The default here has to be for API designers to show why they MUST NOT expose something like this when they're providing an API, not on developers to show that they MUST have the feature. Don't worry, though, most of the DOM gets this wrong. But we don't have to here! Hooray! Lastly, there's no serialization method provided. A toString() implementation might work well. What would the string representation of the object look like? Just the original policy? Yep. One complication is that the page's active policy might be created by the union of several policies (one sent per HTTP, one in a meta tag, etc). Would we want to retain that representation in a string version? Yes. Isn't that the applied policy? Also, speaking as someone writing the union logic himself in JS at the moment, I'd love for union/intersection methods to be made available. They should take SecurityPolicy instances/strings (var-args style) as arguments and return a new SecurityPolicy instance (not locked down). readonly attribute DOMString[] reportURIs; We decided at TPAC to remove the reportURIs getter unless someone has a really good use-case for it. First, that's just totally backwards. If it's in the serialization, it needs to be in your API unless there's a compelling reason to remove it. As I've been working with this stuff, I also think the per-policy domain/setting flags should be exposed on SecurityPolicy instances as well. reportUR[I|L]s should just be part of that list. Next, not only should reportURLs be there, but there should be an event you can catch for violations with the JSON payload you'd send to the server delivered to the DOM as well. One open issue: I'm not sure If allowsEval, allowsInlineScript, and allowsInlineStyle should just be boolean getters or if they should stay methods. I like the idea of converting these `allowEval()`-style calls to read-only booleans. Perhaps 'isActive' as well. Also, it's unclear if the current document's policy should simply be a locked-down instance of a SecurityPolicy class that has accessors for each of the policy items (script-src, object-src, style-src, img-src, media-src, frame-src, font-src, connect-src). I think that's more or less what the current interface does. (e.g. `document.SecurityPolicy.allowsFontFrom('xxx')` is an accessor for the effective permissions granted via the 'font-src' directive). Would you prefer more direct access to the policy? We'd shied away from that on the assumption that this interface required less knowledge of CSP in order to usefully include on a page. Should we revisit that question? Yes = ) I think it's good to have the test methods. I also think it's good to have a
Re: CSP 1.1 DOM design
On Mon, Nov 5, 2012 at 10:56 AM, David Bruant bruan...@gmail.com wrote: Le 05/11/2012 11:32, Alex Russell a écrit : On Mon, Nov 5, 2012 at 1:08 AM, Boris Zbarsky bzbar...@mit.edu wrote: On 11/4/12 3:58 PM, Alex Russell wrote: DOMString toString(); This should probably be: stringifier; instead (which in ES will produce a toString on the prototype, but is more clear about the point, and might do different things in other binding languages). Other binding languages don't matter, but OK. I heard Google is working on this Dart thing. Unless Google redefine APIs for every single web browser capability, it will probably need to define WebIDL bindings for Dart. But what do I know... You know, we should go talk to the guys who designed the Dart DOM...oh, wait, that's me (and arv and jacobr and jmesserly)! We did *exactly* that: http://www.dartlang.org/articles/improving-the-dom/ The W3C/WebIDL DOM sucks and every self-respecting language will re-define the API, preserving the invariants and basic functionality, but aligning the surface area, types, and calling conventions with the idioms and intrinsics of the host language: Python: http://docs.python.org/2/library/xml.etree.elementtree.html Ruby: http://rubydoc.info/gems/hpricot/0.8.6/frames Java: http://www.jdom.org/news/index.html Dart: http://www.dartlang.org/articles/improving-the-dom/ http://api.dartlang.org/docs/bleeding_edge/dart_html.html Yes, it's a lot of work, but if you're not taking care to create a great API for one of your most frequently-used libraries, you're screwing your language and your users. I posit that every language with enough users to matter will do this exercise (JS has done so many times over in the form of the ubiquitous library tax that slows so many sites). FWIW, we can still use WebIDL as a stepping stone to fix the b0rken JS bindings. But we need to collectively stop pretending that: 1. We should be designing JS APIs though the lens of what WebIDL can/can't do 2. That there are other language consumers of WebIDL-defined DOM APIs that both matter and will not go their own way when presented with un-idiomatic/kludgy designs. Perhaps there's some future world in which we decide that having an IDL to describe API invariants is a good idea (although it doesn't do that today to any reasonable degree), but nobody I know is clamoring for that. Another thing to think about is whether reportURIs should really be an IDL array (which does NOT produce a JS array on the JS side, so it really depends on the expected use cases). I'll advocate for a JS array wherever we surface an array-like collection. It's long past time that we stopped shitting on users with ad-hoc collection types. Arguably, ES6 symbols may give a re-birth to ad-hoc collection types by allowing safe (uncollidable) extension of built-ins. I think an IDL array is fine (as far as I can tell, the difference with a regular array is just a different prototype). That's enough to make it toxic.
Re: CSP 1.1 DOM design
Le 05/11/2012 12:50, Alex Russell a écrit : On Mon, Nov 5, 2012 at 10:56 AM, David Bruant bruan...@gmail.com mailto:bruan...@gmail.com wrote: Le 05/11/2012 11:32, Alex Russell a écrit : On Mon, Nov 5, 2012 at 1:08 AM, Boris Zbarsky bzbar...@mit.edu mailto:bzbar...@mit.edu wrote: On 11/4/12 3:58 PM, Alex Russell wrote: DOMString toString(); This should probably be: stringifier; instead (which in ES will produce a toString on the prototype, but is more clear about the point, and might do different things in other binding languages). Other binding languages don't matter, but OK. I heard Google is working on this Dart thing. Unless Google redefine APIs for every single web browser capability, it will probably need to define WebIDL bindings for Dart. But what do I know... You know, we should go talk to the guys who designed the Dart DOM...oh, wait, that's me (and arv and jacobr and jmesserly)! I wrote every single web browser capability, not DOM. I agree with you about the DOM. The Dart effort (and DOM4 to some extent) is excellent for what it did to the DOM API (great job guys!). Yes, it's a lot of work, but if you're not taking care to create a great API for one of your most frequently-used libraries, you're screwing your language and your users. I posit that every language with enough users to matter will do this exercise (JS has done so many times over in the form of the ubiquitous library tax that slows so many sites). FWIW, we can still use WebIDL as a stepping stone to fix the b0rken JS bindings. But we need to collectively stop pretending that: 1. We should be designing JS APIs though the lens of what WebIDL can/can't do Is anyone really doing this? WebIDL didn't exist a couple of years ago and people were designing APIs anyways. Also, WebIDL is still in flux; if WebIDL is limitating, just ask for a change in WebIDL. I've seen a bunch of posts from Boris Zbarsky in that direction. 1. That there are other language consumers of WebIDL-defined DOM APIs that both matter and will not go their own way when presented with un-idiomatic/kludgy designs. If you've read WebIDL recently, you've realize that only an ECMAScript binding is defined. I'm not sure anyone pretends there is another language consuming WebIDL. I feel you have some misconceptions regarding WebIDL. Perhaps there's some future world in which we decide that having an IDL to describe API invariants is a good idea (although it doesn't do that today to any reasonable degree), but nobody I know is clamoring for that. Another thing to think about is whether reportURIs should really be an IDL array (which does NOT produce a JS array on the JS side, so it really depends on the expected use cases). I'll advocate for a JS array wherever we surface an array-like collection. It's long past time that we stopped shitting on users with ad-hoc collection types. Arguably, ES6 symbols may give a re-birth to ad-hoc collection types by allowing safe (uncollidable) extension of built-ins. I think an IDL array is fine (as far as I can tell, the difference with a regular array is just a different prototype). That's enough to make it toxic. I don't understand this point. I'm not 100% up-to-date on ES6 classes, but it seems that WebIDL arrays are the equivalent of doing class MadeUpName extends Array{}. If that's the case, do you think extending Array using ES6 classes is toxic as well? David
Re: CSP 1.1 DOM design
On Mon, Nov 5, 2012 at 12:14 PM, David Bruant bruan...@gmail.com wrote: Le 05/11/2012 12:50, Alex Russell a écrit : On Mon, Nov 5, 2012 at 10:56 AM, David Bruant bruan...@gmail.com wrote: Le 05/11/2012 11:32, Alex Russell a écrit : On Mon, Nov 5, 2012 at 1:08 AM, Boris Zbarsky bzbar...@mit.edu wrote: On 11/4/12 3:58 PM, Alex Russell wrote: DOMString toString(); This should probably be: stringifier; instead (which in ES will produce a toString on the prototype, but is more clear about the point, and might do different things in other binding languages). Other binding languages don't matter, but OK. I heard Google is working on this Dart thing. Unless Google redefine APIs for every single web browser capability, it will probably need to define WebIDL bindings for Dart. But what do I know... You know, we should go talk to the guys who designed the Dart DOM...oh, wait, that's me (and arv and jacobr and jmesserly)! I wrote every single web browser capability, not DOM. WebIDL is about DOM. Does it even have other users? If you don't expose an API from a C++ impl to a more dynamic host language, it doesn't make sense. To the extent that DOM is C++ objects vended to dynamic languages, yes, I maintain that every API should be re-cast in terms of language-native idioms. WebIDL gets you part of the way there for JS (and formerly for Java). But not the whole way. When it prevents improvements (as it so often does), it's a bug and not a feature. I agree with you about the DOM. The Dart effort (and DOM4 to some extent) is excellent for what it did to the DOM API (great job guys!). Yes, it's a lot of work, but if you're not taking care to create a great API for one of your most frequently-used libraries, you're screwing your language and your users. I posit that every language with enough users to matter will do this exercise (JS has done so many times over in the form of the ubiquitous library tax that slows so many sites). FWIW, we can still use WebIDL as a stepping stone to fix the b0rken JS bindings. But we need to collectively stop pretending that: 1. We should be designing JS APIs though the lens of what WebIDL can/can't do Is anyone really doing this? Part of my job is reviewing this sort of proposal and let me assure you that *everyone* does this. IDL *is handy. *More to the point, it's the language of the specs we have now, and the default mode for writing new ones is copy/paste some IDL from another spec that looks close to what I need and then hack away until it's close. This M.O. is exacerbated by the reality that most of the folks writing these specs are C++ hackers, not JS developers. For many, WebIDL becomes a safety blanket that keeps them from having to ever think about the operational JS semantics or be confronted with the mismatches. WebIDL didn't exist a couple of years ago and people were designing APIs anyways. ...in IDL. WebIDL is descended from MIDL/XPIDL which is descended from CORBA IDL. WebIDL is merely a compatible subset + JS-leaning superset. Also, WebIDL is still in flux; if WebIDL is limitating, just ask for a change in WebIDL. I've seen a bunch of posts from Boris Zbarsky in that direction. Heh. Who do you think advocated for DOM prototypes in the right locations? Or has been continuiously advocating that DOM designs not use create* but instead lean on new? ;-) 1. That there are other language consumers of WebIDL-defined DOM APIs that both matter and will not go their own way when presented with un-idiomatic/kludgy designs. If you've read WebIDL recently, you've realize that only an ECMAScript binding is defined. Also my doing from TPAC 2011. I'm not sure anyone pretends there is another language consuming WebIDL. Your tried to. I feel you have some misconceptions regarding WebIDL. Perhaps there's some future world in which we decide that having an IDL to describe API invariants is a good idea (although it doesn't do that today to any reasonable degree), but nobody I know is clamoring for that. Another thing to think about is whether reportURIs should really be an IDL array (which does NOT produce a JS array on the JS side, so it really depends on the expected use cases). I'll advocate for a JS array wherever we surface an array-like collection. It's long past time that we stopped shitting on users with ad-hoc collection types. Arguably, ES6 symbols may give a re-birth to ad-hoc collection types by allowing safe (uncollidable) extension of built-ins. I think an IDL array is fine (as far as I can tell, the difference with a regular array is just a different prototype). That's enough to make it toxic. I don't understand this point. I'm not 100% up-to-date on ES6 classes, but it seems that WebIDL arrays are the equivalent of doing class MadeUpName extends Array{}. If that's the case, do you think extending Array using ES6
Re: CSP 1.1 DOM design
Le 05/11/2012 13:57, Alex Russell a écrit : On Mon, Nov 5, 2012 at 12:14 PM, David Bruant bruan...@gmail.com mailto:bruan...@gmail.com wrote: Le 05/11/2012 12:50, Alex Russell a écrit : On Mon, Nov 5, 2012 at 10:56 AM, David Bruant bruan...@gmail.com mailto:bruan...@gmail.com wrote: Le 05/11/2012 11:32, Alex Russell a écrit : On Mon, Nov 5, 2012 at 1:08 AM, Boris Zbarsky bzbar...@mit.edu mailto:bzbar...@mit.edu wrote: On 11/4/12 3:58 PM, Alex Russell wrote: DOMString toString(); This should probably be: stringifier; instead (which in ES will produce a toString on the prototype, but is more clear about the point, and might do different things in other binding languages). Other binding languages don't matter, but OK. I heard Google is working on this Dart thing. Unless Google redefine APIs for every single web browser capability, it will probably need to define WebIDL bindings for Dart. But what do I know... You know, we should go talk to the guys who designed the Dart DOM...oh, wait, that's me (and arv and jacobr and jmesserly)! I wrote every single web browser capability, not DOM. WebIDL is about DOM. Does it even have other users? I think Anne pointed a potential misunderstanding in his message. I personally use DOM for what it literally stands for. For the rest, I say browser capability or browser APIs or web APIs. I read WebIDL is about DOM as a non-sense with my definition, but understanding that we have a different definition, it makes more sense. If you don't expose an API from a C++ impl to a more dynamic host language, it doesn't make sense. To the extent that DOM is C++ objects vended to dynamic languages, yes, I maintain that every API should be re-cast in terms of language-native idioms. WebIDL gets you part of the way there for JS (and formerly for Java). But not the whole way. When it prevents improvements (as it so often does), it's a bug and not a feature. I largely agree. Now, it just means that WebIDL needs to be improved. Yes, it's a lot of work, but if you're not taking care to create a great API for one of your most frequently-used libraries, you're screwing your language and your users. I posit that every language with enough users to matter will do this exercise (JS has done so many times over in the form of the ubiquitous library tax that slows so many sites). FWIW, we can still use WebIDL as a stepping stone to fix the b0rken JS bindings. But we need to collectively stop pretending that: 1. We should be designing JS APIs though the lens of what WebIDL can/can't do Is anyone really doing this? Part of my job is reviewing this sort of proposal and let me assure you that /everyone/ does this. IDL /is handy. /More to the point, it's the language of the specs we have now, and the default mode for writing new ones is copy/paste some IDL from another spec that looks close to what I need and then hack away until it's close. This M.O. is exacerbated by the reality that most of the folks writing these specs are C++ hackers, not JS developers. For many, WebIDL becomes a safety blanket that keeps them from having to ever think about the operational JS semantics or be confronted with the mismatches. Interesting. I wasn't aware of that. Any idea as to how to improve the state of things? It seems to be much more a human problem than a WebIDL problem. Even if WebIDL improves, people will likely still do the copy/paste dance, no? WebIDL didn't exist a couple of years ago and people were designing APIs anyways. ...in IDL. WebIDL is descended from MIDL/XPIDL which is descended from CORBA IDL. WebIDL is merely a compatible subset + JS-leaning superset. The WebIDL defines an ECMAScript binding and that's a huge step forward. DOM2 ECMAScript bindings is how I discovered that specs really are made by human beings and are subject to being incomplete or inaccurate. I agree WebIDL has limitations, but it's going in the right direction, I feel. Also, WebIDL is still in flux; if WebIDL is limitating, just ask for a change in WebIDL. I've seen a bunch of posts from Boris Zbarsky in that direction. Heh. Who do you think advocated for DOM prototypes in the right locations? Or has been continuiously advocating that DOM designs not use create* but instead lean on new? ;-) I'm aware of your work in this field. Your QCon London 2012 talk [1] shows where you want to go to and it's promising. I was not trying to say that you haven't done anything, but that the solution is to improve WebIDL (regardless of how much things have gotten better already). Also, as I said above, it seems that the problem is not that much in WebIDL as a language, but rather WebIDL-as-people-use-it and I'm not sure WebIDL as
Re: CSP 1.1 DOM design
David Bruant wrote: This M.O. is exacerbated by the reality that most of the folks writing these specs are C++ hackers, not JS developers. For many, WebIDL becomes a safety blanket that keeps them from having to ever think about the operational JS semantics or be confronted with the mismatches. Interesting. I wasn't aware of that. Any idea as to how to improve the state of things? It seems to be much more a human problem than a WebIDL problem. Even if WebIDL improves, people will likely still do the copy/paste dance, no? What Alex describes is inherent in having any IDL language between native implementations and JS clients. Going through the exercise Alex advocated earlier for testing API completeness, of implementing using JS instead of C++, is one way to try to overcome this problem. Boris and probably others have experience here, since Proxies in ES6 allow implementation where JS without Proxies was insufficient. We could get rid of WebIDL and specify interfaces only in JS, but without enough declarative forms that is too abstraction-leak-prone and high-overhead. Beating on WebIDL with the JS stick seems like the way to go. /be P.S.: Kudos to Alex, Arv, et al. for fighting the good fight!
CSP 1.1 DOM design
Hi all, Looking at Section 3.4 of the CSP 1.1 draft [1], I'm noticing that the IDL specified feels very, very strange to use from the JS perspective. For instance, the name document.SecurityPolicy would indicate to a mere JS hacker like me that the SecurityPolicy is a class from which instances will be created. Instead, it's an instance of the SecurityPolicy interface. A more idiomatic name might be document.policy, document.csp, or document.securityPolicy as leading-caps tend to be reserved for classes, not instances. Similarly, it's not possible (AFAICT) to new-up an instance of SecurityPolicy and no API provided for parsing a policy to understand how it would react. Lastly, there's no serialization method provided. A toString() implementation might work well. Here's some IDL and sample code that shows how it might be repaired: [NamedConstructor=SecurityPolicy, NamedConstructor=SecurityPolicy(DOMString policy), NamedConstructor=SecurityPolicy(DOMString policy, DOMString origin)] interface SecurityPolicy { readonly attribute DOMString[] reportURIs; bool allowsEval(); bool allowsInlineScript(); bool allowsInlineStyle(); bool allowsConnectionTo(DOMString url); bool allowsFontFrom(DOMString url); bool allowsFormAction(DOMString url); bool allowsFrameFrom(DOMString url); bool allowsImageFrom(DOMString url); bool allowsMediaFrom(DOMString url); bool allowsObjectFrom(DOMString url); bool allowsPluginType(DOMString type); bool allowsScriptFrom(DOMString url); bool allowsStyleFrom(DOMString url); bool isActive(); DOMString toString(); }; // Examples from the draft: var isCSPSupported = !!document.securityPolicy; // or: var isCSPSupported = (typeof SecurityPolicy != undefined); var isCSPActive = document.securityPolicy.isActive(); // Parse an ssl-only policy as though it were applied to example.com and then test it: var policy = new SecurityPolicy( default-src https:; script-src https: 'unsafe-inline'; style-src https: 'unsafe-inline', https://example.com;); // Can I load a font over HTTP? policy.allowsFontFrom(http://example.com/;); // false One open issue: I'm not sure If allowsEval, allowsInlineScript, and allowsInlineStyle should just be boolean getters or if they should stay methods. Also, it's unclear if the current document's policy should simply be a locked-down instance of a SecurityPolicy class that has accessors for each of the policy items (script-src, object-src, style-src, img-src, media-src, frame-src, font-src, connect-src). I'm inclined to say yes. Thoughts? [1]: https://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html#script-interfaces--experimental