-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Disallow non-templates as interpolations in Polymer.html #5023
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
lib/utils/html-tag.html
Outdated
* they are not intended as a replacement for Polymer data-binding. | ||
* Templates can be composed by interpolating `HTMLTemplateElement`s in | ||
* expressions in the JavaScript template literal. The nested template's | ||
* `innerHTML` is inluced in the containing template. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'inluced' => 'included'
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's add a Polymer.htmlLiteral
(bikeshed) so users have a way of getting a, say, imported string into a template.
Polymer.html`${Polymer.htmlLiteral(foo)}`
@sorvell sounds good. I would want to offer this as another template tag so that it can only be used on literals, not on string variables, and it should disallow interpretations of plain strings. For a function that can consume any string, I would want |
Given that 2.4 got tagged already, I think we should merge this as-is for a quick 2.4.1. We can always add more supported data types without breaking changes. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We talked about this in our meeting. I am okay with this change, given that the unsafeHTML
function will be provided soon too.
P.S. build fails because you need to update the TypeScript types (this sadly also takes into account docs)
Allows composition of strings into html templates constructed with `Polymer.html`. This is useful for composing values into styles or other places where an html template would not compose. ``` const css = Polymer.htmlLiteral`background: red;` Polymer.html`<style>:host { ${css} }</style>` ```
lib/utils/perf-tester.js
Outdated
|
||
'use strict'; | ||
|
||
class PerfTester extends HTMLElement { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sorvell Was this class intended to be committed in this PR? If so, we need some docs on what it actually does and how we can use it (assuming you used it to measure the performance of the changes in this PR).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
argh, mistakenly committed; removing.
lib/utils/html-tag.html
Outdated
@@ -12,13 +12,31 @@ | |||
(function() { | |||
'use strict'; | |||
|
|||
class HTMLLiteral { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
docs
lib/utils/html-tag.html
Outdated
@@ -12,13 +12,31 @@ | |||
(function() { | |||
'use strict'; | |||
|
|||
class HTMLLiteral { | |||
constructor(string) { | |||
this.innerHTML = string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wouldn't name this innerHTML
, this isn't an element. I'd go with value
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was an attempt to write less code, since both types can return their string value via innerHTML
; fair that it's a bit short-cutty.
lib/utils/html-tag.html
Outdated
*/ | ||
Polymer.htmlLiteral = function(strings, ...values) { | ||
return new HTMLLiteral(values.reduce((acc, v, idx) => | ||
acc + literalValue(v) + strings[idx + 1], strings[0])); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style nit: 4 space indent for wrapped expressions
lib/utils/html-tag.html
Outdated
if (value instanceof HTMLTemplateElement) { | ||
return /** @type {!HTMLTemplateElement} */(value).innerHTML; | ||
if (value instanceof HTMLTemplateElement || value instanceof HTMLLiteral) { | ||
return /** @type {!HTMLTemplateElement | !HTMLLiteral} */(value).innerHTML; | ||
} else { | ||
throw new Error(`non-template value passed to Polymer.html: ${value}`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this message should probably be updated to allow for htmlLiteral too
lib/utils/html-tag.html
Outdated
class HTMLLiteral { | ||
constructor(string) { | ||
this.innerHTML = string; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider adding a toString()
implementation with the literal value
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
lib/utils/html-tag.html
Outdated
* they are not intended as a replacement for Polymer data-binding. | ||
* Templates can be composed by interpolating `HTMLTemplateElement`s in | ||
* expressions in the JavaScript template literal. The nested template's | ||
* `innerHTML` is included in the containing template. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should also include using htmlLiteral
It seems like a pretty major problem to not be able to separate the HTML templates into separate files. This is absolutely key to being able to write modular code. I would naturally think it would be a developers choice if they wanted to add these arbitrary files. It sort of seems like it's just a way to keep code within a Polymer environment(I don't want to be confrontational, I do hope I'm wrong, as @justinfagnani says). Perhaps I haven't fully understood what's involved, but if I can't use arbitrary HTML templates, it's actually a deal breaker for me in terms of Polymer vs Vanilla WC. The Components I was using stopped working a few days ago because I was importing html strings into my code and using them to build templates. The end user doesn't build web components, so is it fair to say that the restriction and the bubble wrap only affects developers who should be checking for XSS anyway ? |
@alchmy: You may want to check out the HTML Modules discussion. |
Ok Thanks. I'll have a read through it. |
@alchmy this isn't about not being able to break up templates, this is about not opening XSS vulnerabilities by blindly allowing user input to flow into privileged templates. You can compose templates, they just have be composed of values produced by the |
This is to prevent XSS vulnerabilities from accidentally interpolating unsafe user-provided values into templates that would be interpreted as HTML.
With this change, the only values that can be used to construct templates are JS template literals and other HTML templates. We're not checking that HTML templates are created from Polymer.html, but if an app is letting user-controlled values into an HTML template as HTML, it already has an XSS.
cc @arthurevans and @katejeffreys for documenting this change.