W3C home > Mailing lists > Public > whatwg@whatwg.org > March 2010

[whatwg] XSS safe templating

From: Mike Samuel <mikesamuel@gmail.com>
Date: Fri, 12 Mar 2010 08:51:42 -0800
Message-ID: <178b8d441003120851q13f13f9eu80f993d8559acdf@mail.gmail.com>
2010/3/12 Henri Sivonen <hsivonen at iki.fi>:
> On Mar 11, 2010, at 20:18, Mike Samuel wrote:
>
>> I think I can probably do without new HTML5 stuff.
>
> OK. One supplemental point:
>
> On Mar 10, 2010, at 20:15, Mike Samuel wrote:
>
>> document.write can be wrapped. ?But the wrapper would still need to
>> know the insertion-mode.
>> If the insertion mode were exposed, or at least some context were
>> given -- enough to know whether the next char if not something that
>> changed the current token, would be interpreted as
>> ?* inside a tag
>> ?* outside a tag in a comment / application instruction / doctype
>> ?* outside a tag in a PCDATA/RCDATA/CDATA context and ideally in what
>> kind of containing tag
>> ?* outside a tag in a CDATA section.
>
> That's not the insertion mode. That's the tokenizer state.

Yep.  I think that I can make do without the insertion mode by doing
purely lexical analysis.

> Whenever a script that is eligible to write to the stream starts running, the tokenizer is in the "data" state. Therefore, if you control all the scripts on the page, and wrap document.write(), you already have a stable initial tokenizer state provided to you by the host browser's parser and you can predict the state transitions from there.

Yep.

> If you have arbitrary other scripts on the page whose execution may be interleaved with the execution of your wrapper in unexpected ways, you've already lost XSS-safety overall.

True.  For this to hold, I need to be able to get to a known good state.
One way is for the wrapping script to run before anything else does a write.
Another way might be heuristic -- check that there is no body content.
Another might be to write out something that is guaranteed to end all
partial tokens --
  document.write(" <!-- </script> </style> </textarea> </title> </xmp>
</listing> ]]> ?> !> \"> <!-- '-->");
and just abort if that ends up introducing a plaintext element onto
the document.

> --
> Henri Sivonen
> hsivonen at iki.fi
> http://hsivonen.iki.fi/
>
>
>
Received on Friday, 12 March 2010 08:51:42 UTC

This archive was generated by hypermail 2.4.0 : Wednesday, 22 January 2020 16:59:21 UTC