On Tue, Oct 27, 2009 at 3:54 PM, Brandon Sterne <[email protected]> wrote: > I couldn't find a comment that summarizes the model you are proposing so > I'll try to recreate your position from memory of our last phone > conversation.
I'll try to find the time to write a complete specification. > I believe you advocate a model where a site specifies the directives it > knows/cares about, and everything else is allowed. The design I suggest is simpler than this. The site just lists which restrictions it would like applied to its content. Each directive is purely subtractive: adding more directives only further restricts what the site can do. > This model would make > the default "allow" directive unnecessary. The main idea is to allow sites > to restrict the things it knows about and not have to worry about > inadvertently blocking things it doesn't consider a risk. That's correct. I also think it makes sense to package the restrictions into "meaningful" directives that address specific threats. > My main objection to this approach is that it turns the whitelist approach > we started with into a hybrid whitelist/blacklist. The design is a pure blacklist. Just like turning off unused operating system services, content restrictions should let web developers turn off features they aren't using. > The proposal doesn't > support the simple use case of a site saying: > "I only want the following things (e.g. script and images from myself). > Disallow everything else." The problem is that "everything else" is ill-defined. Should we turn off canvas? That's a "thing" that's not a script or an image from myself. CSP, as currently design, as a hard-coded universe of "things" it cares about, which limits its use as a platform for addressing future use cases. It is a poor protocol that doesn't plan for future extensibility. > Under your proposal, this site needs to explicitly opt-out of every > directive, including any new directives that get added in the future. Not really. When we invent new directives, sites can opt in to them by adding them to their policy. Just like you can opt in to new HTML5 features by adding new HTML tags to your document. > We're > essentially forcing sites to maintain an exhaustive blacklist for all time > in order to avoid us (browsers) accidentally blocking things in the future > that the site forgot to whitelist. Web developers are free to ignore CSP directives that mitigate threats they don't care about. There is no need for web developers to maintain an exhaustive list of anything. > Under your proposed model, a site will continue to "function correctly" only > in the sense that nothing will be blocked in newer implementations of CSP > that wouldn't also have been blocked in a legacy implementation. That's correct. The semantics of a given CSP policy does not change as new directives are invented and added to the language, just as the semantics of an old HTML document doesn't change just because we invented the canvas tag. > From my > perspective, the blocking occurs when something unexpected by the site was > included in the page. In our model, the newer implementation, while > potentially creating an inconsistency with the older version, has also > potentially blocked an attack. You're extremely focused on load resources and missing the bigger picture. > Are you suggesting that a blocked resource is more likely to have come from > a web developer who forgot to update the CSP when s/he added new content > than it is to have been injected by an attacker? I'm not suggesting this at all. Nothing in my argument has to do with probabilities. > This seems like a > dangerous assumption. All we are getting, in this case, is better > consistency in behavior from CSP implementation-to-implementation, but not > better security. Consistency between implementation is essential. Mitigating important threats is also essential. Nether is more important than the other. >> 2) Modularity. We would be free to group the directives into whatever >> modules we liked because there would be no technical interdependence. > > I actually don't see how opt-in vs. opt-out has any bearing at all on module > interdependence. Maybe you can provide an example? Sure. Suppose I want to implement enough of CSP to let web developers protect themselves from Type-I and Type-II XSS (e.g., because I view that the lion's share of the benefit). How can I do that in the current CSP design without affecting the targets of XMLHttpRequest? Surely you agree that restricting the targets of XMLHttpRequests has little (if anything) to do with mitigating Type-I or Type-II XSS, yet these parts of CSP are so interdependent that I'm forced to implement all of them or none of them. > Let's also not forget that CSP modularity really only helps browser vendors. Complexity hurts everyone. The current monolithic CSP design is overly complex for the security it provides. There are much simpler designs that provide the same security benefits. > From the perspective of websites, CSP modules are just one more thing that > they have to keep track of in terms of which browsers support which modules. In the subtractive design, web developers don't need to care at all which browsers support which modules. They can simply turn off the features they're not using. Browsers that understand those modules will provide additional security. Browsers that don't understand those modules will be blissfully ignorant. > I support the idea of making it easier for other browser vendors to > implement CSP piecemeal, but our primary motivation should remain making the > lives of websites and their users better. Again, tightly coupling unrelated concepts leads to complexity and hurts everyone. >> 3) Trivial Combination. Instead of the current elaborate algorithm >> for combining policies, we could simply concatenate the directives. >> An attacker who could inject a Content-Security-Policy header could >> then only further reduce his/her privileges. > > In the case of an injected header, this is already the case now. We > intersect both policy sets, resulting in a combined policy more restrictive > than either of the two separate policies. The combination algorithm is quite complex. To implement the algorithm, I need to compute the semantics of both policies and then interset those semantics. In the design I propose, one simply uses the standard algorithm for coalescing HTTP headers. > If we are talking about an attacker who can inject an additional directive > into an existing CSP header then, yes, the attacker could "relax" the policy > intended to be set by the site. I'm not sure how much I care about this > case. By using a subtractive design, we need not worry about an attacker injecting policy at all. Injected policy (either into a single HTTP header field or into an additional HTTP header field) is of no use to the attacker because the injected directives only disable more features. >> 4) Syntactic Simplicity. Instead of two combination operators, ";" >> for union and "," for intersection, we could simply use "," and match >> standard HTTP header syntax. > > Okay, sure. > >> Balancing against these pros, the con seem to be that we hope the >> additive, opt-out syntax will prod web developers into realizing that >> adding "script-src inline" to the tutorial code they copy-and-paste is >> more dangerous than removing "block-xss". > > Those seem equivalent to me, so I'm not sure which model your example > favors. If those seem equivalent, they why not adopt the less complex, more extensible design? In this entire email, you haven't stated why we should prefer the tightly coupled design / opt-out over the modular opt-in design. > In general, I'm slightly skeptical of the view that we need to base our > design around the fact that admins will copy-paste from tutorials. None of my four points make this argument. I'm not advocating basing our design on this assumption. > Sure, > this will happen in practice, but what is the probability that such a site > is a high value target for an attacker, and by extension how important is it > that such a site gets CSP right? Remember, a site cannot make their > security profile any worse with CSP than without it. > > I do want CSP to be easy to get right. I should do some homework and > collect some stats on real world websites to support the following claim, > but I still maintain that a HUGE number of sites will be able to benefit > greatly from a minimal policy such as "allow 'self'". Even "allow *" would > be a gigantic improvement in terms of blocking all the common XSS vectors. The "allow *" policy does not mitigate *any* Type-I or Type-II XSS vulnerabilities. If you, an expert in this topic, does not understand this fact, then I have little hope that web developers will be able to understand how to use CSP, as currently designed, correctly. > My contention is that CSP tutorials should (and will if we evangelize > properly) instruct sites to start with a minimal policy such as "allow > 'self'" and incrementally add policy until the site behaves as expected. > This approach will result in minimal policy set and will tend to be optimal > in terms of bandwidth and risk profile. I agree that we should make the most useful policy textual short. No one is arguing against this proposition. Adam _______________________________________________ dev-security mailing list [email protected] https://lists.mozilla.org/listinfo/dev-security
