Re: Making it easier to deploy CSP.

On Mon, Feb 15, 2016 at 1:46 AM, Conrad Irwin <conrad.irwin@gmail.com>
wrote:

> The behaviour of `unsafe-dynamic` you propose seems pretty confusing to
> describe to me (you have to distinguish between "parser-inserted" and not),
> and I'm not sure how it integrates with other browser functionality.
>

This could likely be simplified to: *scripts created with
document.createElement('script') *without much loss of generality.

One of the reasons for this distinction is to bless scripts dynamically
created by APIs which aren't injection-prone in practice. As a
counterexample, markup passed to innerHTML or document.write() is
"parser-inserted", and these two APIs are common sources of XSS -- we
should not propagate trust to scripts inserted into the page by these APIs
because that would significantly weaken DOM XSS protection (which is
probably a moot point for innerHTML specifically, because scripts added
with innerHTML won't be executed).

A particular case I'm confused about is:
> 1. create a new document with document.implementation.createDocument()
> 2. use that document to safely parse untrusted HTML (as is done by
> DOMPurify)
> 3. use appendChild() to copy nodes from that document into a second
> document
>
> It seems like the scripts would run in that case (assuming the target
> document had a CSP of `unsafe-dynamic`), even though the scripts were
> created by the parser?
>

Interesting... I think either behavior would be acceptable for the purposes
of unsafe-dynamic so it's a question of what makes more sense for the spec
and implementations. If you explicitly call
appendChild([script-from-another-document]) then you are presumably doing
it intentionally so the script could be blessed to execute. At the same
time, we could stick to the very narrow definition of "script needs to be
created with document.createElement()" and in practice the value of
unsafe-dynamic wouldn't be diminished (the majority of JS APIs and widgets
will be covered).


> I'm also worried that it randomly tinkers with other parts of the CSP in
> peculiar ways (a `hash` or a `nonce` is required to run the initial script,
> you can't use an origin or `unsafe-inline` or `unsafe-eval`).
>
> I'm not totally against the idea, because it seems useful to get more
> people using a CSP, but I think the current approach is very complicated.
> It might be simpler to add `unsafe-dynamic` that lets you do
> appendChild(script); but which doesn't break any of the other CSP
> directives, and solve the compatibility issue with server-side user-agent
> detection.
>

These are both fair points. I mentioned some of our original rationale for
requiring nonces and ignoring the whitelist in my reply to Martin --
overall, there is precedent for adding new CSP directives in a
backwards-compatible way, e.g. nonce-source causes 'unsafe-inline' to be
ignored, so it seemed like continuing along the same vein might be
preferable.

Do you see any alternative approach which would not require user-agent
detection? (I'm worried that it could be another non-trivial obstacle to
CSP adoption, on top of some already difficult challenges).

Cheers,
-Artur



> Sent via Superhuman <https://superhuman.com/?utm_source=signature>
>
> On Sun, Feb 14, 2016 at 3:58 PM, Martin Thomson<martin.thomson@gmail.com>
> wrote:
>
>> On 14 February 2016 at 16:39, Devdatta Akhawe <dev.akhawe@gmail.com>
>> wrote:
>>
>> Personally, my preference for increasing complexity is in the order---web
>> apps and then browsers and then standards.
>>
>> The priority of constituencies would (perfectly) disagree on this point.
>>
>> https://www.w3.org/TR/html-design-principles/#priority-of-constituencies
>>
>> The thing I'm trying to wrap my head around is how this fits with the
>> general CSP design pattern. How does adding this directive narrow the set
>> of things that are permitted? It actually appears to do the opposite. The
>> purpose being to give dynamically inserted scripts an exemption.
>>
>
>

Received on Wednesday, 17 February 2016 02:35:52 UTC