- From: Mike West <mkwst@google.com>
- Date: Tue, 8 Jan 2013 11:08:26 +0100
- To: Yoav Weiss <yoav@yoav.ws>
- Cc: Adam Barth <w3c@adambarth.com>, Tanvi Vyas <tanvi@mozilla.com>, Florian Lasinger <florian@lasinger.org>, "public-webappsec@w3.org" <public-webappsec@w3.org>
- Message-ID: <CAKXHy=fFypMkOqZ8SMzV_DWeOOuNDbDLMsN5+KMXQnQQJGuyoQ@mail.gmail.com>
In an "and" world, applying nonces to external scripts is no problem, and in fact gives the developer even more control over exactly which scripts are executed where on her page. That benefit obviously goes away in an "or" world. On the other hand, one use-case that's been suggested for nonces would allow third-party content (widgets, ads, etc) to include otherwise disallowed scripts by passing a nonce into the bootstrap script. That is, `<script src="https://example.com/ads.js?nonce=12345"></script>` would allow the trusted ad network to load whatever scripts it needed in order to display the required content. Since ad networks often load scripts from different servers depending on the specific ad being shown, this might be a valuable benefit of applying nonces to external scripts in an "or" world. I don't actually have strong opinions on which direction we go here, I see good arguments for both; I do, however, want to ensure that the end result is straightforward to reason about. I'm a bit worried that it's already too complex. -- 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 10:58 AM, Yoav Weiss <yoav@yoav.ws> wrote: > 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 10:09:18 UTC