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

On Mon, Jan 25, 2016, at 03:05 AM, David Ross wrote:
> IFRAMEs require significant engineering work to implement in many
> cases, and aren't particularly flexible in some ways.

IFRAMEs can absolutely be a hassle.  And I like the feature set you
propose and the goal of making it easier to safely include untrusted
content into the page.  If the right way is hard/impossible, many will
just find something that looks like magic pixie dust, sprinkle it
around, and call it a day.

My primary concern is about cognitive burden.  IFRAMEs are a known
concept.  They separate conceptually separate content into separate
documents with separate globals.  If I
querySelectorAll()/getElementById() in my main page, I know that I'm not
accidentally going to pull out an attacker-provided element.  As
currently proposed, it sounds like everyone hacking on a page using
SafeNode would need to be aware of this.  Now, obviously,
querySelector*/etc. can be fixed by spec, but then what has been created
sounds a lot like the Shadow DOM.  And then the question is why aren't
we just using the Shadow DOM instead of inventing new things?


The reason I brought up use-cases is because, to my mind/experience,
there's basically two main scenarios with user/third-party-authored
content:

1) Bite-size: Rich-text mark-up for text messages, tweets, forum posts,
etc.  Markup exists for some combination of user self-expression and
semantics (quoting, MathML, etc.).

2) Meal-size: The user-content is a document in its own right.  For
example HTML mails with ads and custom styling.

Reading between the lines of what you are saying about IFRAMEs, it
sounds like the use-case you have in mind is closer to "bite-size", but
you are engineering functionality for "meal-size".  I think the
bite-size case is arguably best-addressed by an HTML sanitizer using a
white-list.  Safety can be provided/guaranteed and you get all of your
non-rectangular styling goals, etc.  And I think the meal-size case
should be addressed with the existing platform solution, IFRAMEs.

And meal-size wise, it's worth calling out that IFRAMEs can be important
for usability given the rise of mobile devices and the need to
pinch-and-zoom.  If the document has its own idea of what a reasonable
font-size is, users may absolutely need to zoom the document.  While a
"transform: scale" hack can be applied at any level of the DOM, arguably
it's cleaner and there can be more benefits to be doing it in an iframe
in terms of allowing the browser engine to understand and optimize
what's going on[1].

> In contrast, it should be possible to create Safe Nodes on-the-fly
> whenever you want to safely render a little snippet of untrusted
> markup.  You mostly don't need to think through all these
> considerations, just create a Safe Node and add it into the DOM.
> Configuration options are available, but they're tuned to the use
> cases you might care about and they don't create much of an
> opportunity for shooting yourself in the foot.

This seems like a great proposal for a custom-element implementation
using existing libraries or new libraries that could be built out. 
Easy-to-use safety with the existing platform implementation, webdevs
are saved from additional cognitive burden of new possible platform
magic behavior.

For example <SafeNode><template><muahaha>I better have been injected via
createElement or realllly safely quoted into the
document.</muahaha></template></SafeNode>.

SafeNode could even try and be all things to all people by having the
sanitizer library do a speculative sanitizing pass.  If it encounters
simple markup meeting all whitelist requirements, it can perhaps simply
inject the elements directly into the document.  If more extensive
features are used it can place the content in a shadow DOM, perhaps
slurping an explicit scoped stylesheet into place or something.  And if
it encounters something potentially dangerous but allowed, it spins up
an iframe.  If the SafeNode creator knows they want iframes, they can
specify that as an attribute and skip directly to that.
 
> Though I would agree that in a world with seamless IFRAMEs, it should
> be possible to build a decent Safe Node polyfill.

Definitely agreed if s/polyfill/library/.  As in, I think it makes sense
to build the use-case solution first and only propose platform changes
if/when it proves reasonable/necessary.  And it's my assertion that the
platform changes can likely be made to existing web platform features. 
But again, you may have use-cases in mind that I'm not conceiving of.

Andrew

1: This is wildly speculative on my part other than the fact that meta
viewport is a thing
(https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta#Attributes).
 The most recent time we rev'ed the Firefox OS mail app's HTML display,
Gecko only supported Asynchronous-Pan-and-Zoom (APZ) at the top level
(eg the email app itself), so we were faking things by using "transform:
scale(blah)" on our body iframes to zoom the HTML mail as part of the
enclosing page context.  (So no scrolling inside the iframe, the
iframe's effective size was always the same as its scroll size.)  The
APZ/Compositor got very good at building and optimizing the layer tree
so that only the visible portion of the iframe was rendered and
painted... most of the time.  If we could have just tagged the iframe as
<iframe zoomable-doc seamless /> then I think everyone would have been
much happier.

Received on Monday, 25 January 2016 22:41:55 UTC