[whatwg] some thoughts on sandboxed IFRAMEs

Tab Atkins Jr. jackalmage at gmail.com
Mon Jan 25 12:32:46 PST 2010


On Mon, Jan 25, 2010 at 1:51 PM, Michal Zalewski <lcamtuf at coredump.cx> wrote:
>> This has been proposed before. The concern is that many authors would be
>> likely to make mistakes in their selection of "random" tokens that would
>> lead to significant flaws in the deployment of the feature.
>>
>> srcdoc="" is less prone to errors. Only " and & characters need to be
>> escaped. If the " character is not escaped, then a single " character in
>> the input will cause the comment to break.
>
> My counterargument, as stated later in the thread, is quite simple:
> the former *forces* you to implement a security mechanism, else the
> functionality will break. You can still use a bad token, but you are
> required to make the effort.

Ah, but the devil is in the details.

Of the two escaping requirements for @srcdoc, only escaping " is
required for security reasons. (Forgetting to escape & will just
result in spurious entities sometimes, but no security issues.)
However, use of " in comments should be reasonably common, and if it
is left unescaped, will immediately truncate the content there (the
rest of the comment will attempt to be interpreted as attributes or
other elements).

Thus, if you fail to escape your "s, it should fail *quickly* and
*obviously* on *innocuous* content.  As well, as soon as it happens,
the obvious fix is the correct one.

On the other hand, getting your token-generation wrong will only fail
when someone guesses your guard token and attacks your site.  Ordinary
comments will still work just fine.

> If we extend sandboxed iframes with srcdoc, seamless frames,
> text/html-sandboxed, and <iframe> rendering performance improvements,
> it actually becomes close to a comprehensive solution, and I am happy
> with this (other than a vague feeling that we just repurposed <iframe>
> to be some sort of a <span> ;-).

In the end that's sorta what we're doing.  ^_^

> 1) Some other security mechanisms (CORS, anti-clickjacking controls,
> XSS filter controls) rely on separate HTTP headers instead. Is there a
> compelling reason not to follow that lead - or better yet, to unify
> all security headers to conserve space?

HTTP headers won't cause the content to fail in browsers that don't
understand them.  Mimetypes will in at least *some* legacy browsers.
I know that some versions of IE do content-sniffing for HTML-like
content.

> 2) People may conceivably want to sandbox other document types (e.g.,
> SVG, RSS, or other XML-based formats rendered natively, and offering
> scripting capabilities). Do we want to create "-sandboxed" MIME types
> for each? The header approach would fix this, too.

Possibly.  Are those document types going to be rendered in any way?
SVG can be sent with an HTML mimetype now, at least.

>>> 2.1) The ability to disable loading of external resources (images,
>>> scripts, etc) in the sandboxed document. The common usage scenario is
>>> when you do not want the displayed document to "phone home" for privacy
>>> reasons, for example in a web mail system.
>>
>> Good point. Should we make sandbox="" disable off-origin network requests?
>
> That would be great. I think Adam proposed we have a separate
> sandbox="..." toggle for this. Whether it's on or off by default
> probably doesn't matter much.

I think this is a good idea.  Adam argues against it being effective
for preventing exfiltration, but it's also useful for the common
use-case of disabling images in comments.  This would also prevent
people using <video> or <audio> in comments.  It would still allow the
site author to allow self-hosted files to be used with any of these
tags, but it would protect from, say, goatse trolls.

>>> 2.2) The ability to disable HTML parsing. On IFRAMEs, this can actually
>>> be approximated with the excommunicated <plaintext> tag, or with
>>> Content-Type: text/plain / data:text/plain,. On token-guarded SPANs or
>>> DIVs, however, it would be pretty damn useful for displaying text
>>> content without the need to escape &, <, >, etc. "Pure" security benefit
>>> is limited, but as a phishing prevention and display correctness
>>> measure, it makes sense.
>>
>> I don't really understand the use case here; could you elaborate?
>
> One use case is a web forum or a web mail interface where you want to
> display a message, but specifically don't want HTML formatting. Or,
> performance permitting, the same could be used for any text-only entry
> fields displayed on a page. These are common XSS vectors, and they are
> not readily addressed by sandboxed <iframe> + srcdoc="...", because
> this will not render as expected:
>
> User's favorite smiley face is: <iframe srcdoc="&lt;O&gt;_&lt;O&gt;"></iframe>
>
> Having a drop-in solution for this would be pretty nice, and very easy
> to implement, too: just force text/plain, do not sniff.

I agree with this as well.  I very commonly have inputs that should
take plaintext only, not html.

> <span>[server-sanitized string]</span>
> <iframe srcdoc="[server-escaped string]"></iframe>
> <span guard=[token]>[any string]</span guard=[token]>
>
> The first two options will not immediately fail if you forget about or
> mess up escaping or sanitization - and people to, all the time. The
> last option just works, unless you purposefully sabotage your code by
> using "1234", or can't generate a random number / session token on
> server side (in which case, you are hosed already - session cookies
> can be guessed, too). The last option strikes me as a bit less
> error-prone.

As I said above, the second one *should* fail, quite quickly, with
ordinary harmless content if you forget to escape the " in it, and the
way to fix it is both trivial and obvious.  On the other hand, the
third one you've listed will appear to work perfectly fine as long as
you can at least match your tokens on either end, but won't fail until
someone guesses your tokens and attacks you.  (And even then, it might
not be immediately obvious - they could put only non-visible content
after their smuggled-in </span guard=[token]>, so there's no visible
effect from the attack.)

Summary of suggestions to follow.

~TJ


More information about the whatwg mailing list