On Mar 7, 2013, at 12:58 PM, Adam Barth wrote:
> On Thu, Mar 7, 2013 at 11:23 AM, Brendan Eich <brendan@secure.meer.net> wrote:
>> I'd like to hear more about the security concerns with template strings. I
>> couldn't find that at a glance among the three links Ojan footnoted.
>
> The general problem with template strings is that they're an XSS risk.
> Essentially, we're encouraging authors to mix untrusted data into
> strings that will later be parsed by the HTML parser. If the attacker
> is clever in selecting these untrusted strings, he'll be able to cause
> the remainder of the string to be parsed differently than the author
> intends.
>
> var firstName = [...];
> var lastName = [...];
> header.innerHTML = `<h1>Welcome ${ firstName } ${ lastName }!</h1>`;
>
> If firstName and lastName are are user-controlled (i.e., untrusted),
> the above is an XSS vulnerability. For example, the attacker can set
> firstName to "<img onerror='alert(/pwned/)'>".
>
> We have lots of implementation experience with these sorts of
> string-based template systems because they're widely used in languages
> like PHP. Our broad experience is that they lead to buggy, XSS-prone
> code.
>
> The general anti-pattern to avoid is the following:
>
> template + input -> string -> HTML parser -> DOM
>
> A more secure approach is to first parse the template into a DOM and
> then add the untrusted input into the DOM as text nodes. In this
> approach, the attacker's maliciously crafted firstName would simply
> end up as a text node and would not execute as script. (You might or
> might not like other aspects of E4H, but one of its virtues is that it
> follows this more secure pattern.)
>
> I understand that someone (either the author or the browser) could
> write an HTML tag for template strings that implements the more secure
> pattern, but most authors will simply use the default mode, which
> follows the insecure pattern. As a result, this language feature will
> lead to many XSS vulnerabilities and general sadness in the world.
>
So, what's the issue? We can't force end user's to not use (with string based APIs such as innerHTML) untagged template strings just like we can't force them to not use regular strings and concatenation to construct strings that they assign to innerHTML. But we can provide via template strings a more secure mechanism for dynamically constructing such markup (for various embedded languages).
Note the template tags aren't required to return string values. If you want, you can design the HTML tag to return a special kind of object (for example an encapsulated and signed DOM subtree) and provide new APIs that only accept such objects and reject strings.
Allen