W3C home > Mailing lists > Public > public-script-coord@w3.org > January to March 2013

Re: E4H and constructing DOMs

From: Adam Barth <w3c@adambarth.com>
Date: Sat, 9 Mar 2013 08:58:18 -0800
Message-ID: <CAJE5ia9HuMWeM6mpRAnoSZRcLSXhO_pXP7oN3LoaUju=2-+MmQ@mail.gmail.com>
To: Domenic Denicola <domenic@domenicdenicola.com>
Cc: Allen Wirfs-Brock <allen@wirfs-brock.com>, Jonas Sicking <jonas@sicking.cc>, Anne van Kesteren <annevk@annevk.nl>, Rick Waldron <waldron.rick@gmail.com>, Adam Klein <adamk@chromium.org>, Ojan Vafai <ojan@chromium.org>, Brendan Eich <brendan@secure.meer.net>, Ian Hickson <ian@hixie.ch>, "rafaelw@chromium.org" <rafaelw@chromium.org>, Alex Russell <slightlyoff@chromium.org>, "public-script-coord@w3.org" <public-script-coord@w3.org>, "Mark S. Miller" <erights@google.com>
(Consolidating replies again.)

On Fri, Mar 8, 2013 at 1:27 PM, Mike Samuel <mikesamuel@gmail.com> wrote:
> 2013/3/8 Adam Barth <w3c@adambarth.com>:
>> tl;dr: No one is disputing that string templates as currently designed
>> are insecure by default and will lead authors to write code filled
>> with XSS vulnerabilities.  I recommend removing string templates for
>> the spec until these security issues are resolved.
>
> I oppose this on the grounds that it is better than current ad-hoc
> content creation practices, and can lead to a principled solution in a
> way that AST approaches cannot.

It's clear that you oppose removing string templates from the
specification, but you still haven't brought forth any technical
arguments disputing that that string templates as currently designed
are insecure by default and will lead authors to write code filled
with XSS vulnerabilities.

> My argument is that we need to produce minimal language extension
> points to allow experimentation by security researchers.

I can see what that's appealing to you as a security researcher, but I
doubt that's the best thing for the vast majority of ECMAScript
authors.

On Fri, Mar 8, 2013 at 5:53 PM, Jonas Sicking <jonas@sicking.cc> wrote:
> On Fri, Mar 8, 2013 at 1:15 PM, Adam Barth <w3c@adambarth.com> wrote:
>> Right, that's why the example in my first email is XSS:
>>
>> ---8<---
>> var firstName = [...];
>> var lastName = [...];
>> header.innerHTML = `<h1>Welcome ${ firstName } ${ lastName }!</h1>`;
>> --->8---
>
> It's hard to say if the blame for this is with quasis or with
> .innerHTML though. I.e. would not having quasis cause people to use
> your AST based template system, or would they just use string
> concatenation?

I don't think it's that important to assign blame.  There's plenty of
evidence that developers are very happy with AST-based solutions when
done well.  For example, many, many developers use prepared statements
for SQL and Haml for HTML.

Again, not advocating for E4H, but the following seems to have good
developer ergonomics:

---8<---
var firstName = [...];
var lastName = [...];
header.appendChild(@<h1>Welcome { firstName } { lastName }!</h1>);
--->8---

It also has the advantage of executing faster because we don't need to
parse every fragment of the template twice.  :)

> I agree that AST solutions have advantages. But the cost of
> introducing them is really high and as far as I can tell there is no
> way to create a generic AST-based solution. I.e. if we wanted to do
> something SQL-like for querying databases we'd have to invent a whole
> new JS syntax for that too.

That seems like less of a problem to me than giving developers a giant
security footgun.  If we implement string templates as currently
designed, we're going to spend the next decade cleaning up the
security mess.

My goal isn't to convince you to implement a particular alternative to
string templates.  My goal is to convince you that string templates
(as currently design) are terrible for security and therefore you
shouldn't implement them.

On Fri, Mar 8, 2013 at 6:04 PM, Domenic Denicola
<domenic@domenicdenicola.com> wrote:
> From: Adam Barth [mailto:w3c@adambarth.com]
>
>> Right, that's why the example in my first email is XSS:
>
>>     var firstName = [...];
>>     var lastName = [...];
>>     header.innerHTML = `<h1>Welcome ${ firstName } ${ lastName }!</h1>`;
>
>> Whereas the E4H equivalent would not be:
>
>>     var firstName = [...];
>>     var lastName = [...];
>>     header.appendChild(@<h1>Welcome { firstName } { lastName }!</h1>);
>
>
> I must be missing something, but from my reading you are not gaining anything in the ES4H example over the string templates example, if of course you modify the last line to be
>
>     header.innerHTML = html`<h1>Welcome ${ firstName } ${ lastName }!</h1>`;
>
> In particular, as has been explained in this thread a few times, there's no reason why browsers can't ship a built-in `html` template handler that does the same AST-based DOM parsing on the passed template string that ES4H would do on the source string following the @-sign, and subsequently returns the `outerHTML` of the resulting DOM element.

Even if browser did include such a quasis handler, that would still
not be the default handler.  That means string templates would be
insecure by default and will lead authors to write code filled with
XSS vulnerabilities.

> Indeed, since string templates don't even need to return strings, you could do
>
>     header.appendChild(htmlel`<h1>Welcome ${ firstName } ${ lastName }!</h1>`);
>
> where `htmlel` just returns an HTML element constructed using that same algorithm (instead of the `outerHTML` of that element).
>
> At this point it seems like you are bikeshedding over `@` vs. `htmlel` or `{}` vs. `${}`, which leads me to believe I must be missing your argument, especially since you emphasize you're not wedded to ES4H and thus presumably not wedded to `@` or `{}`.

I don't care at all about the syntax.  If you want to keep backtick as
the operator, that's fine.  What's important to me are the following:

1) The template system parses the trusted template content separately
from the untrusted input data.  In particular, it should fill the
untrusted data into the leaves of AST produced by parsing the template
rather than parsing the untrusted data.

2) The template system does the above by default.

Specifically, I would be perfectly happy with the following syntax:

header.appendChild(`<h1>Welcome ${ firstName } ${ lastName }!</h1>`);

as long as this "hello, world" template is not XSS.

Adam


On Fri, Mar 8, 2013 at 6:04 PM, Domenic Denicola
<domenic@domenicdenicola.com> wrote:
> From: Adam Barth [mailto:w3c@adambarth.com]
>
>> Right, that's why the example in my first email is XSS:
>
>>     var firstName = [...];
>>     var lastName = [...];
>>     header.innerHTML = `<h1>Welcome ${ firstName } ${ lastName }!</h1>`;
>
>> Whereas the E4H equivalent would not be:
>
>>     var firstName = [...];
>>     var lastName = [...];
>>     header.appendChild(@<h1>Welcome { firstName } { lastName }!</h1>);
>
>
> I must be missing something, but from my reading you are not gaining anything in the ES4H example over the string templates example, if of course you modify the last line to be
>
>     header.innerHTML = html`<h1>Welcome ${ firstName } ${ lastName }!</h1>`;
>
> In particular, as has been explained in this thread a few times, there's no reason why browsers can't ship a built-in `html` template handler that does the same AST-based DOM parsing on the passed template string that ES4H would do on the source string following the @-sign, and subsequently returns the `outerHTML` of the resulting DOM element. Indeed, since string templates don't even need to return strings, you could do
>
>     header.appendChild(htmlel`<h1>Welcome ${ firstName } ${ lastName }!</h1>`);
>
> where `htmlel` just returns an HTML element constructed using that same algorithm (instead of the `outerHTML` of that element).
>
> At this point it seems like you are bikeshedding over `@` vs. `htmlel` or `{}` vs. `${}`, which leads me to believe I must be missing your argument, especially since you emphasize you're not wedded to ES4H and thus presumably not wedded to `@` or `{}`.
>
> Look forward to hearing what I missed!
Received on Saturday, 9 March 2013 16:59:22 UTC

This archive was generated by hypermail 2.3.1 : Wednesday, 8 May 2013 19:30:09 UTC