W3C home > Mailing lists > Public > public-webappsec@w3.org > January 2016

Re: In-browser sanitization vs. a “Safe Node” in the DOM

From: David Ross <drx@google.com>
Date: Fri, 22 Jan 2016 13:21:03 -0800
Message-ID: <CAMM+ux49fSbHGezJR7VwWbDyYNSkO-HC8dDC4hkKtqq5XFxBCg@mail.gmail.com>
To: Chris Palmer <palmer@google.com>
Cc: Craig Francis <craig.francis@gmail.com>, Conrad Irwin <conrad.irwin@gmail.com>, "public-webappsec@w3.org" <public-webappsec@w3.org>
Re-reading what I sent, I didn't answer this question directly:
> For example, what is the actual mechanism/algorith/heuristic thsi API would use to enforce the Safe CSS set of policies?
This is where I would need your help.  =)  But I know the limitations
re CSS sanitization, and I don't see how the same limitations would
apply if the browser itself is enforcing the policy.  For example, in
the case of CSS downloaded from an external source, a sanitizer is SOL
and must drop that CSS on the floor.  Assuming external content is
enabled, the Safe Node approach could allow this CSS in a safe manner.

Similarly, code baked into the browser can ratchet up the level of
isolation between CSS in a "Safe Node" and its surrounding DOM.  E.g.:
By putting the Safe Node CSS into something akin to its own namespace.
I have not seen a similar approach that would work for a client-side
sanitizer, though DOMPurify may address it, somehow (?)

Dave

On Fri, Jan 22, 2016 at 1:00 PM, David Ross <drx@google.com> wrote:
>> Do I understand correctly that the motivation behind this proposal is to enable people to assign to someElement.innerHTML?
> I was thinking about the innerHTML usage as just a means to an end.
> The goal is to be able to give web apps a way to make use of untrusted
> markup in a safe way.  The way this is achieved today is with a
> sanitizer.  There was an initial conversation about building
> sanitization into the browser, and my suggestion was that if we're
> thinking about doing that for any reason, perhaps Safe Node would be
> more sensible.
>
> You're right that .innerHTML is an anti-pattern and maybe our best bet
> is to avoid that syntax.  You could imagine a simplification of my
> suggested syntax that rolls everything into one single
> document.createSafeNode() method.
>
>> For example, what is the actual mechanism/algorith/heuristic thsi API would use to enforce the Safe CSS set of policies?
> My argument is that it's smarter to implement policy enforcement
> within Blink / WebKit than it is to implement the same thing reliably
> within custom sanitizer code stapled onto Blink / WebKit.  For
> example, consider the case of the policy that disables script.  The
> browser can quite definitively disable script execution initiated from
> within a particular DOM node.  However a sanitizer has to whitelist
> all the elements and attributes it suspects are capable of initiating
> script execution.  Pushing the policy enforcement to be implemented
> close to the code that is being regulated makes it less likely that
> new browser features will subvert the policy enforcement.  Some things
> that are simply difficult or impossible for sanitizers to regulate in
> a granular way (eg: CSS) are easier to handle with a Safe Node.
>
>> element.innerHTML = purify(untrustworthyString, options...)
>> That seems convenient enough for callers?
> See the pros / cons in my writeup.  And wait, didn't you just argue
> that we shouldn't make use of .innerHTML given it's an anti-pattern?
> =)
>
> Dave
>
> On Fri, Jan 22, 2016 at 12:35 PM, Chris Palmer <palmer@google.com> wrote:
>> Do I understand correctly that the motivation behind this proposal is to
>> enable people to assign to someElement.innerHTML?
>>
>> If so, why is it a goal to enable a well-known anti-pattern? If not, ignore
>> the rest of this message. :)
>>
>> It reminds me a bit of efforts to make 'safe' string
>> concatenation/interpolation APIs to stop SQL injection, in a world where
>> parameterized queries already exist (and often execute faster). Here, we
>> already have document.createElement, document.createTextNode,
>> <element>.appendChild, and so on.
>>
>> In general, enabling well-known anti-patterns seems like a bad idea,
>> especially when they seem to require magic to implement. For example, what
>> is the actual mechanism/algorith/heuristic thsi API would use to enforce the
>> Safe CSS set of policies?
>>
>>> * Safe CSS
>>>  + Prevent anti-XSRF nonce theft via CSS
>>>  + Prevent UI overlay
>>>  + Prevent any identified abuse of existing styles on the page
>>>  + Prevent styles defined within the Safe Node from affecting the
>>> surrounding page
>>
>>
>> Since the usual (reasonable) objection to document.createElement,
>> document.createTextNode, <element>.appendChild, is that it results in
>> verbose, blargy code, I'd rather see an API that makes use of techniques
>> like this
>> https://developer.mozilla.org/en-US/Add-ons/Code_snippets/HTML_to_DOM —
>> filtering parsers. Basically, Cure53's DOMPurify, only standardized and
>> built into the browser and implemented in native code. That way people could
>> do
>>
>>     element.innerHTML = purify(untrustworthyString, options...)
>>
>> That seems convenient enough for callers?
Received on Friday, 22 January 2016 21:21:52 UTC

This archive was generated by hypermail 2.3.1 : Monday, 23 October 2017 14:54:17 UTC