Comments on the Content Security Policy specification

2009-07-16 Thread Ian Hickson

First, let me state up front some assumptions I'm making:

* Authors will rely on technologies that they perceive are solving their 

* Authors will invariably make mistakes, primarily mistakes of omission,

* The more complicated something is, the more mistakes people will make.

I think CSP is orders of magnitude too complicated to be a successful 
security mechanism on the Web.

I believe that if one were to take a typical Web developer, show him this:

   X-Content-Security-Policy: allow self; img-src *;

...and ask him does this enable or disable data: URLs in embed or 
would an onclick='' handler work with this policy or are framesets 
enabled or disabled by this set of directives, the odds of them getting 
the answers right are about 50:50.

Similarly, given the following:

   X-Content-Security-Policy: allow https://self:443

...I don't think a random Web developer would be able to correctly guess 
whether or not inline scripts on the page would work, or whether Google 
Analytics would be disabled or not.

I think that this complexity, combined with the tendency for authors to 
rely on features they think are solvign their problems, would actually 
lead to authors writing policy files in what would externally appear to be 
a random fashion, changing them until their sites worked, and would then 
assume their site is safe. This would then likely make them _less_ 
paranoid about XSS problems, which would further increase the possibility 
of them being attacked, with a good chance of the policy not actually 
being effective.

Other comments:

I'm concerned about the round-trip latency of fetching an external policy 
file. Would the policy only be enforced after it is downloaded, or would 
it block page loading? The former seems like a big security problem (you 
would be vulnerable to an XSS if the attacker can DOS the connection). The 
latter would be unacceptable from a performance perspective. Applying a 
lockdown policy in the meantime would likely break the page (e.g. no 
scripts or images could be fetched).

I think CSP should be more consistent about what happens with multiple 
policies. Right now, two headers will mean the second is ignored, and two 
metas will mean the second is ignored; but a header and a meta will 
cause the intersection to be used. Similarly, a header with both a policy 
and a URL will cause the most restrictive mode to be used (and both 
policies to be ignored), but a misplaced meta will cause no CSP to be 

A policy-uri to a third-party domain is blocked supposedly to prevent an 
XSS from being able to run a separate policy, but then the policy can be 
inclued inline, so that particular hole doesn't seem to be actually 

I don't think UAs should advertise support for this feature in their HTTP 
requests. Doing this for each feature doesn't scale. Also, browsers are 
notoriously bad at claiming support accurately; since bugs will be present 
whatever happens, servers are likely to need to do regular browser 
sniffing anyway, even if support _is_ advertised. On the long term, all 
browsers would support this, and during the transition period, browser 
sniffing would be fine. (If we do add the advertisment, we can never 
remove it, even if all browsers support it -- just like we can't remove 
the Mozilla/4.0 part of every browser's UA string now.)

Ian Hickson   U+1047E)\._.,--,'``.fL   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'
dev-security mailing list

Re: Comments on the Content Security Policy specification

2009-08-11 Thread Ian Hickson
On Thu, 30 Jul 2009, Gervase Markham wrote:
 On 29/07/09 23:23, Ian Hickson wrote:
* Remove external policy files.
 I'm not sure how that's a significant simplification; the syntax is 
 exactly the same just with an extra level of indirection, and if that 
 makes things too complicated for you, don't use them.

Complexity affects everyone, not just those who use it.

* If there are multiple headers, fail to fully closed.
 How is this a simplification? It means that if there are multiple people 
 (e.g. an ISP and their customer) who want input into the policy, the ISP 
 or the customer has to manually merge and intersect the policies to make 
 one header, rather than the browser doing it. In other words, the 
 intersection code gets written 1000 times, often badly, rather than 
 once, hopefully right.

I think in almost all cases, multiple headers will be a sign of an attack 
or error, not the sign of cooperation.

* Combine img-src, media-src, object-src, frame-src
 But then the combined lotsofthings-src would have to be set to the 
 intersection of all the above, which means e.g. far more potential 
 sources of objects (in particular) than you might otherwise want. 
 object-src: none sounds to me like a great idea for a load of sites 
 which also want to display images.
 OTOH, lotsofthings-src: would still be a 
 big improvement over now, where we effectively have lotsofthings-src: 

I think simplification is a win here, even if it makes the language less 
expressive. Obviously, it's a judgement call. I'm just letting you know 
what I think is needed to make this good.

  I'm concerned that people will eventually do something that causes the 
  entire policy to be ignored, and not realise it (yay, I fixed the 
  problem) or will do something that other people will then copy and 
  paste without understanding (well this policy worked for that site... 
  yay, now I'm secure).
 These would be issues with any possible formulation.

It's dramatically reduced if the format fails safe and is of minimal 

   I imagine sites starting with the simplest policy, e.g. allow 
   self, and then progressively adding policy as required to let the 
   site function properly.  This will result in more-or-less minimal 
   policies being developed, which is obviously best from a security 
  This is maybe how competentely written sites will do it. It's not how 
  most sites will do it.
 How do you expect them to do it?

Copy-and-paste from sites that didn't understand the spec, for example 
copying from, and then modifying it more or less at random. 
Or copy-and-paste from some other site, without understanding what they're 

 That's like saying some people will start their Ruby on Rails web 
 application by writing it full of XSS holes, and then try and remove 
 them later. This may be true, but we don't blame Ruby on Rails. Do we?

Ruby on Rails isn't purporting to be a standard.

  You are assuming the person reading all this is familiar with security 
  concepts, with Web technologies, with whitelists and wildcards and 
  so on. This is a fundamentally flawed assumption.
 I don't see how we could change CSP to make it understandable to people 
 unfamiliar with Web technologies and wildcards. I think almost everyone 
 is familiar with the concept of a whitelist, but perhaps under a 
 different name. Any suggestions?

I think the dramatic simplification I described would be a good start. I'd 
have to look at the result before I could really say what else could be 
done to make the language safer for novices.

On Thu, 30 Jul 2009, Daniel Veditz wrote:
   * Drop the allow directive, default all the directives to self
 allow is an important simplification.

I don't think that making policies shorter is the same as simplification. 
In fact, when it comes to security policies, I think simplicity 
corresponds almost directly to how explicit the language is. Any 
implications can end up tripping up authors, IMHO.

  We could remove many of the directives, for example. That would make 
  it much shorter.
 Make what shorter? The spec, certainly, but probably not the typical 
 policy. And if a complex policy needed those directives then eliminating 
 them hasn't really helped.

Making the spec shorter is a pretty important part of simplifying the 
language. The simpler the spec, the more people will be able to understand 
it, the fewer mistakes will occur.

Ian Hickson   U+1047E)\._.,--,'``.fL   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'
dev-security mailing list