W3C home > Mailing lists > Public > public-web-security@w3.org > January 2011

Re: [Content Security Policy] Proposal to move the debate forward

From: Adam Barth <w3c@adambarth.com>
Date: Fri, 28 Jan 2011 12:03:08 -0800
Message-ID: <AANLkTikpvY0juAMATD4EiRipUvBFsqHDKa12JyM6RtAo@mail.gmail.com>
To: Gervase Markham <gerv@mozilla.org>
Cc: Brandon Sterne <bsterne@mozilla.com>, public-web-security@w3.org
On Fri, Jan 28, 2011 at 2:26 AM, Gervase Markham <gerv@mozilla.org> wrote:
> On 27/01/11 20:39, Adam Barth wrote:
>> Is there some reason we need to synchronize on a "version 1" feature
>> set?  I'd prefer an extensible model more like HTML where we can each
>> implement different parts of CSP on different schedules.  For example,
>> something more in the spirit of
>> <http://blog.whatwg.org/html-is-the-new-html5>.
> I don't think anyone can stop you from implementing what you want to
> implement on your own schedule :-)

Well, the current design of CSP is difficult to implement
incrementally.  Even the simplest policies affect font loading.  It's
very convoluted to define a subset of the language that lets you
control script execution without also controlling font loading.

> On the other hand, if all the browsers
> implement different initial subsets of CSP, that's not particularly helpful
> for site authors. If a discussion of what the initial feature set is gives
> each browser maker some idea of what the others are likely to implement, and
> also exposes decision makers to the arguments in support of each feature,
> that will be a win.

The model works well for CSS.  Different vendors implement different
features at different times, including experimental features.  The
popular ones get folding into the main spec.  That seems like the
model we want here, both now and for the future.

>>> 2. Content restrictions
>>>   a. allow: catch-all for content-types not specified in policy
>>>   b. img-src: domains permitted to load images
>>>   c. media-src: domains permitted to load<video>,<audio>
>>>   d. object-src: domains permitted to load plugin content
>>>   e. frame-src: domains permitted to be loaded in<iframe>s
>>>   f. font-src: domains permitted to load fonts
>>>   g. xhr-src: domains permitted to send XHR to
>>>   h. style-src: domains permitted to load stylesheets
>> I'm not that excited about these features.  Maybe I don't understand
>> the use cases sufficiently, but the benefits from these features seem
>> outweighed by their complexity.
> The general use case for this type of restriction is: I want to restrict the
> sites which can load content, so a content injection can't pull in arbitrary
> content from evil.com. You could argue that all we need for this really is
> the "allow" directive. The further use case for the subdivisions is that it
> should be possible to trust some sites for some things (e.g. YouTube for
> video) without trusting them for everything.

That's not really a use case.  That's a description of a mechanism.
What goal am I trying to achieve by using that mechanism?

>> For example, what is the use case for
>> being able to restrict font-src?
> Typekit or Google Fonts. I can certainly imagine wanting to do:
> allow: 'self'; font-src: fonts.typekit.com
> without allowing typekit to provide any other sort of content.

Right, but why would I want to block loading fonts from other places?

> Or, to think about it another way: if I only have "allow", and want to allow
> images from www.somewhere.com, I have to be pretty confident about the
> security of www.somewhere.com and the fact that they won't get broken into
> so someone can upload a dodgy script and then use an XSS hole in my code to
> compromise my users. If I have img-src, I don't need to have any reassurance
> about their security, because all they can send me are images.

I agree that controlling which scripts can execute on your page is
useful for mitigating XSS.  I don't understand why controlling which
fonts can be loaded by your page has any security impact.

>> Here is a use case that seem related to the above that might be worth
>> thinking about:
>> 1) My site is entirely served over HTTPS, but my developers keep
>> including mixed content by mistake.  I wish I could set a policy for
>> my site that prevented me accidentally loading insecure content.
>> Maybe there are other good use cases for this feature that I don't
>> understand?
> This use case was considered for CSP.
> X-Content-Security-Policy: allow https://*:443
> https://wiki.mozilla.org/Security/CSP/Specification#Sample_Policy_Definitions
> , example 4.

Indeed.  I'm saying that I agree that's a good use case that I'd be
happy to see supported.

>>> 4. Clickjacking protection
>>>   a. frame-ancestors: list of domains permitted to embed the resource
>>>      in an iframe
>> IMHO, clickjacking is a quagmire.  I'd love to see a solution, but I'm
>> not really convinced that this is it.  I'd like to avoid being drawn
>> into yet another discussion on this topic, if at all possible.
> What is incorrect about the following sequence of logic?
> 1) Most sites don't use frames.
> 2) All those sites don't need to be framed to work properly.
> 3) All those sites could therefore use frame-ancestors: none.
> 4) frame-ancestors: none entirely defeats clickjacking.
> 5) The CSP frame-ancestors mechanism provides a total solution to
>   clickjacking for most sites in a single statement.

I mean, we've already got X-Frame-Options deployed in more browsers
than frame-ancestors.  If you crawl the web, it doesn't appear to be
overly popular.  I guess that's more of an empirical observation than
some logical fallacy in the above.

>>> 5. Options (mechanisms to change default CSP behaviors)
>>>   a. inline-script: permit inline script to execute
>>>   b. eval-script: permit eval() and related functions to be used
>> If we manage to disentangle (1) from the rest of these features, then
>> we probably don't need (a).
> Why is the necessity or not of (a) dependent on whether we implement "the
> rest of these features"?

Well, imagine we had a policy directive like the following:

mitigate-xss-but-allow-scripts-from <origin-list>

That directive would disable inline script and restrict where you
could load external scripts from.  There'd be no reason to have an
inline-script directive.  If you wanted to allow inline-script, you'd
just remove that directive from you policy.  Having both
mitigate-xss-but-allow-scripts-from and inline-script in your policy
is non-sensical because the later defeats the point of the former.

>> Enabling inline-script defeats the script
>> controls, so the way folks should "enable" inline script is by not
>> using the script controls.
> Not if we support script-nonce. One can easily imagine people using
> inline-script and script-nonce together.

We could either decide that script-nonce implied "allow inline scripts
with the nonce" or we could have a directive that meant exactly that.
Having inline-script decoupled from script-nonce and hoping they'll
play well together is an invitation to disaster.

>> Obviously we need a policy delivery mechanism.  I suspect there are
>> strong use cases for both (a) and (b).  The previous CSP proposal has
>> a complex mechanism for merging policies.  IMHO, we should go with the
>> much simpler "first one wins" strategy.  Headers trump<meta>  tags.
>> Textually earlier headers trump textually later headers.
> The use case for the more complex policy was that sites may want a certain
> site-default policy, but be allowed to tighten it for particular pages.
> Or, to put it another way: if a site already has a CSP policy, "first one
> wins" means that page authors with no access to headers cannot set a more
> strict policy even if they want to.
> OTOH, if that doesn't convince us. "first one wins" could be
> backwardly-compatibly extended to "each subsequent one only tightens" if
> later on people give us more compelling reasons.

I guess I don't see that use case as being very compelling.  If you
want to set different policies for different parts of your site, then
you might as well just overwrite the header.

Received on Friday, 28 January 2011 20:04:19 UTC

This archive was generated by hypermail 2.3.1 : Tuesday, 6 January 2015 20:26:18 UTC