In whatwg/dom#831, there is a discussion about whether it is ok to add new html elements and/or attributes to the platform, if those additions could enable scripts to run. The issue/position put forth (e.g. here and here) is that it is possible for a site to configure an HTML sanitizer such that:
If that situation is possible, then the conclusion (again, as presented here and here) is that we either must:
If this is the "policy", it would seem to preclude several new features being proposed:
This logically follows, since it is possible to construct a sanitizer that uses a deny-list, and constructs that deny list using only the element/attribute combinations available at a given point in time. Any new elements or attributes, even if they are "dangerous", would not be present in the deny list, and would therefore be allowed through this sanitizer.
Should this be the "policy" for the web platform?
One alternative viewpoint would be that we should instead work to guard against this situation:
There are several comments on whatwg/dom#831 that appear to be supportive of this alternative way to think about risk mitigation (e.g. this, this, this, and (I think) this). The difficulty, of course, becomes defining "well configured" sanitizers. This is not an easy job, and likely requires some judgement calls to be made, and data to be gathered. A few categories of sanitizer could potentially be pre-defined as "not well configured", e.g. those using fixed deny-lists. While this "policy" is a bit harder to define, it does seem to re-open the possibility of adding new elements and attributes to the web platform.
IMO, it will be hard to have this discussion without more/better examples.
The policy being discussed, and which I attempted to articulate in the other thread about declarative shadow DOM, is simply stated: "ensure 100% backwards compatibility with any sanitizer that works today or could work today in principle, no matter how oddly constructed."
I think it's clearer when we give these things names, and I would propose to call this policy "No Sanitizer Left Behind," NSLB.
NSLB stands in contrast with another rule which I think is much closer to the rule we actually follow on the web: "ensure 100% backwards compatibility with any _reasonable_ sanitizer, and certainly with any sanitizer in widespread use today." Let's call that "No Good Sanitizer Left Behind," NGSLB, in opposition to NSLB.
In the declarative shadow DOM thread, I argued that <template shadowroot> runs afoul of NSLB and that <template onshadowroot> would/does, too.
On the other hand, NGSLB would probably allow <template onshadowroot>, and <template shadowroot> would probably be allowed, too.
I say "probably" because NGSLB requires us to look at actual _data_. What do real sanitizers actually _do?_ _Do_ they refuse to sanitize templates? _Do_ they strip all attributes starting with on, just to be safe, or is there a widespread sanitizer with a deny list? etc.
In your statement at the top of this thread, you give three other examples of what you thought NSLB would forbid:
I don't think I agree with two of these examples. I think 2 would actually be _allowed_ under NSLB, and 1 might be as well; 3 would be forbidden, but that's probably good, actually.
I think new HTML elements are not strictly forbidden by NSLB, because HTMLUnknownElement exists. No sanitizer can be said to "work" today if it sanitizes only known, defined HTML elements, because it would be vulnerable on all modern browsers to attackers who made up a tag and attached an HTML event handler to it, e.g. <foo onmouseover="alert('xss')">foo</foo>. If the traditional behavior of browsers had been to leave unknown elements inert, _then_ a deny-list approach to sanitizing elements would work, but it absolutely doesn't work today, and so, at least in principle, we're allowed to introduce new HTML elements without violating NSLB, as long as it doesn't provide any _new_ vector for running scripts.
If you look at the explainer for declarative custom elements, it's basically just declarative shadow DOM wrapped in a new <definition> element. I see no way to use the <definition> element to run scripts except by virtue of the fact that the declarative shadow DOM _inside_ the <definition> element might be forbidden under NSLB.
Which is to say, declarative custom elements might well depend on declarative shadow DOM, and declarative shadow DOM in its currently spec'd implementation (<template shadowroot="open"><script>alert('ohai'')</script></template>) does seem to run afoul of NSLB, but that's just restating the original problem: declarative shadow DOM violates NSLB.
Declarative _custom elements_ don't violate NSLB except by using declarative shadow DOM, and if for some reason we thought it made sense to ship declarative custom elements _without_ declarative shadow DOM, I can foresee no _NSLB_ problems with that.
onBlah attributes) would be forbidden, and that's good, actuallyAs for forbidding any _new_ HTML events (onBlah attributes)… I think that might well be right. But, truth be told, I think _that_ is actually extremely reasonable. I think we should at the very least _hesitate_ before introducing any new HTML attribute (onBlah or otherwise) where the value of the attribute contains JavaScript that the browser will run.
If NSLB were officially the law of the land, and as a result there were a moratorium on new onBlah HTML attributes, I don't think we'd miss much, as long as it remained legal to use the _existing_ HTML attributes (onclick ,onkeydown, onpointermove, etc.)
As for Open UI specifically, it's hard to know in advance what specs Open UI will generate, but the only two proposals linked off of https://open-ui.org/ mention no _new_ event attribute names. <checkbox> would have change and input events… those both already exist. <select> includes change, click, and keydown events. Those all already exist, too. Those would all be legal under NSLB as a result.
Indeed, I'm not aware of anything on the Open UI list of form controls (breadcrumb, card, datepicker, slider, switch, table, tabs) that _would_ need a new onBlah attribute. I think we probably could forbid new onBlah attributes forever-ish, as long as the web continues to have the traditional keyboard + pointer interaction model it has today. (Maybe if/when it becomes possible to create and define VR objects in HTML, we can reopen this discussion…?)
NSLB asks us to "ensure 100% backwards compatibility with any sanitizer that works today or could work today in principle, no matter how oddly constructed."
But the web _has_ added new HTML events in recent years without a major international XSS incident. I believe (without proof) that no sanitizer in common use today uses a deny list for HTML events precisely _because_ it's just so obvious that new ones come along every day. Anyone who started with a deny list for HTML attributes and got screwed when we added onpointermove learned their lesson years ago!
In the declarative shadow DOM thread, it was suggested that perhaps <template onshadowroot> would/should be allowed, even if <template shadowroot> isn't. IMO, if anyone thinks creating new onBlah HTML attributes should be allowed, then they have, wittingly or not, left the path of NSLB and accepted NGSLB into their hearts.
I think we can probably live with NSLB. But maybe we shouldn't.
What is the "security policy" for adding new events and elements to the Web Platform?
Where there is a trade-off between new features and security:
From the side bench:
Reason: Otherwise there will not be stable progress.
Explanation: Existing obsoleteware is foremost the fault of the 4 big vendors as they don't force the software to be updated xor uninstalled (after a grace period of not updating such as 3 months) by default. Second to that it is the responsbility of the user. Example: If I use dual-wire-electricity it is not the fault of a lamp producer if I hurt myself in case the lamp comes with all the security feautres that are recent.
On forced updates XOR disables: This is tough especially on microsoft and apple as they are required to disable Internet Explorer / Edge and Safari on old versions, also on their mobile devices. There should be ways to re-enable (users should have control) but it should not be the default.
Reason: Users need to feel save and trust the platform, otherwise they will move to walled gardens and closed gateways (despite that there, tracking happens too, but it is out of reach of the users to even realize/decide).
Explanation: Evercookie, fingerprinting, cookies, retargeting, detection of user agents though hardware architecture etc. is NOT what users want. As at least one big vendor is big into ads, this policy will be hard to push through, yet the most important.
This feature is the most important and only diminished by outdated client side software (see rule 1).
Bad examples: This for instance has been ignored when introducing canvas, webgl and possibly webasm regarding fingerprinting
Thus if say shadow dom introduces such vectors, then it is a problem. I cannot judge if streaming shadow doms would do that, but in case it would, that's a problem (see rule 2).
Say outdated or badly written software (versions) such as load balancers, proxies, apache/nginx, php, fpm, node, wordpress, sanitizers should be considered but ultimately disregarded if there is no easy upgrade path respecting issues.
Reason: Web standards are not responsible for bad citizins. They are however responsible for making sure the technology itself is no threat to security (see rule 3). This for instance has been ignored when introducing canvas, webgl and possibly webasm.
@dfabulich thanks for the entertaining post, and the (better?) names for the two cases here. I agree with your points, mostly. You're right that new HTML elements, because of HTMLUnknownElement, should be ok to add. But new events, which come with "on*" content attributes, aren't. And as you rightly point out, we're adding new events all the time. I'm wondering if this issue has come up on the various threads discussing the APIs adding new events. (E.g. Picture-in-Picture, WebXR, Web Bluetooth, etc.) From a quick search, it doesn't look like this issue has been brought up at all elsewhere. But perhaps I missed it. If so, I'm wondering what the mitigation was.
It was probably clear from my OP, but I'm definitely in the NGSLB camp. Blocking forward progress on a purely-hypothetical situation seems like not the right trade off here. Of course, if there's a real issue on real sites today, let's make sure we address it.
Can the feature be used to bypass a safelist-based sanitizer (https://github.com/WICG/sanitizer-api might help making that concrete) is probably the bar, but it will also always depend. (Maybe this should move to whatwg/html?)
Can the feature be used to bypass a safelist-based sanitizer (https://github.com/WICG/sanitizer-api might help making that concrete) is probably the bar, but it will also always depend. (Maybe this should move to whatwg/html?)
I think I agree with that bar - safelist-based sanitizers should continue to be safe. And I believe they are here, as the "shadowroot" attribute will not be on existing safelists. The main "worry" on this thread seems to be denylist-based sanitizers, which don't seem to be future proof or secure on their own.
I agree that this should probably be on whatwg/html - I don't think I have permission to move it. Do you?
Most helpful comment
IMO, it will be hard to have this discussion without more/better examples.
The policy being discussed, and which I attempted to articulate in the other thread about declarative shadow DOM, is simply stated: "ensure 100% backwards compatibility with any sanitizer that works today or could work today in principle, no matter how oddly constructed."
I think it's clearer when we give these things names, and I would propose to call this policy "No Sanitizer Left Behind," NSLB.
NSLB stands in contrast with another rule which I think is much closer to the rule we actually follow on the web: "ensure 100% backwards compatibility with any _reasonable_ sanitizer, and certainly with any sanitizer in widespread use today." Let's call that "No Good Sanitizer Left Behind," NGSLB, in opposition to NSLB.
In the declarative shadow DOM thread, I argued that
<template shadowroot>runs afoul of NSLB and that<template onshadowroot>would/does, too.On the other hand, NGSLB would probably allow
<template onshadowroot>, and<template shadowroot>would probably be allowed, too.I say "probably" because NGSLB requires us to look at actual _data_. What do real sanitizers actually _do?_ _Do_ they refuse to sanitize templates? _Do_ they strip all attributes starting with
on, just to be safe, or is there a widespread sanitizer with a deny list? etc.NSLB doesn't forbid as much as you'd think
In your statement at the top of this thread, you give three other examples of what you thought NSLB would forbid:
I don't think I agree with two of these examples. I think 2 would actually be _allowed_ under NSLB, and 1 might be as well; 3 would be forbidden, but that's probably good, actually.
New HTML Elements would be allowed under NSLB
I think new HTML elements are not strictly forbidden by NSLB, because
HTMLUnknownElementexists. No sanitizer can be said to "work" today if it sanitizes only known, defined HTML elements, because it would be vulnerable on all modern browsers to attackers who made up a tag and attached an HTML event handler to it, e.g.<foo onmouseover="alert('xss')">foo</foo>. If the traditional behavior of browsers had been to leave unknown elements inert, _then_ a deny-list approach to sanitizing elements would work, but it absolutely doesn't work today, and so, at least in principle, we're allowed to introduce new HTML elements without violating NSLB, as long as it doesn't provide any _new_ vector for running scripts.Declarative custom elements might be allowed, too… _without shadow DOM_
If you look at the explainer for declarative custom elements, it's basically just declarative shadow DOM wrapped in a new
<definition>element. I see no way to use the<definition>element to run scripts except by virtue of the fact that the declarative shadow DOM _inside_ the<definition>element might be forbidden under NSLB.Which is to say, declarative custom elements might well depend on declarative shadow DOM, and declarative shadow DOM in its currently spec'd implementation (
<template shadowroot="open"><script>alert('ohai'')</script></template>) does seem to run afoul of NSLB, but that's just restating the original problem: declarative shadow DOM violates NSLB.Declarative _custom elements_ don't violate NSLB except by using declarative shadow DOM, and if for some reason we thought it made sense to ship declarative custom elements _without_ declarative shadow DOM, I can foresee no _NSLB_ problems with that.
New HTML events (
onBlahattributes) would be forbidden, and that's good, actuallyAs for forbidding any _new_ HTML events (
onBlahattributes)… I think that might well be right. But, truth be told, I think _that_ is actually extremely reasonable. I think we should at the very least _hesitate_ before introducing any new HTML attribute (onBlahor otherwise) where the value of the attribute contains JavaScript that the browser will run.If NSLB were officially the law of the land, and as a result there were a moratorium on new
onBlahHTML attributes, I don't think we'd miss much, as long as it remained legal to use the _existing_ HTML attributes (onclick,onkeydown,onpointermove, etc.)As for Open UI specifically, it's hard to know in advance what specs Open UI will generate, but the only two proposals linked off of https://open-ui.org/ mention no _new_ event attribute names.
<checkbox>would havechangeandinputevents… those both already exist.<select>includeschange,click, andkeydownevents. Those all already exist, too. Those would all be legal under NSLB as a result.Indeed, I'm not aware of anything on the Open UI list of form controls (breadcrumb, card, datepicker, slider, switch, table, tabs) that _would_ need a new
onBlahattribute. I think we probably could forbid newonBlahattributes forever-ish, as long as the web continues to have the traditional keyboard + pointer interaction model it has today. (Maybe if/when it becomes possible to create and define VR objects in HTML, we can reopen this discussion…?)But maybe HTML events prove that NSLB is wrong and NGSLB is right
NSLB asks us to "ensure 100% backwards compatibility with any sanitizer that works today or could work today in principle, no matter how oddly constructed."
But the web _has_ added new HTML events in recent years without a major international XSS incident. I believe (without proof) that no sanitizer in common use today uses a deny list for HTML events precisely _because_ it's just so obvious that new ones come along every day. Anyone who started with a deny list for HTML attributes and got screwed when we added
onpointermovelearned their lesson years ago!In the declarative shadow DOM thread, it was suggested that perhaps
<template onshadowroot>would/should be allowed, even if<template shadowroot>isn't. IMO, if anyone thinks creating newonBlahHTML attributes should be allowed, then they have, wittingly or not, left the path of NSLB and accepted NGSLB into their hearts.I think we can probably live with NSLB. But maybe we shouldn't.