While sitting is a couple of talks at BlackHat Abu Dhabi, I got to thinking about how we can improve browser defenses. Much of the problems we have are due to the same problem that has plagued systems since Captain Crunch first blew his whistle at 2600 hertz; the data and control channel are the same. Your browser can't tell the difference between attacker injected script and legitimate scripts and happily responds to both. It's what allows XSS and CSRF attacks, and even SQLi. Framebusting is a great example of this, a site owner doesn't want his page to sit in a frame, but has to compete in the arms race against attackers who want the site to be framed. What we need is some way for a site-owner to specify a security policy, that exists outside of the application. The site-owner should be able to specify that the site shouldn't be framed, and the browser respect that, without an attacker able to inject an alternate set of instructions (or at least not trivially via the actual app). Right now, even if a site-owner is aware of the problem, with a smart security team, all they can do is compete in the arms race.
There's a corollary to the problem however, third-party content. The web is made of mashups. Even single-source content providers still include a raft of third-party content, from RSS feeds, to advertising or JQuery. This introduces a whole set of potential interconnected vulnerability that a site owner can't control. If an ad provider is hacked and used to distribute malware, then the site-owner's only choice (if detected) is to remove the ad.
We need something that can give a site owner control back of their application. Something that can be specified outside of the page content. A security policy that puts all the controls we have available to us with software (enforced security policy & ability to disable features not required) back in the hand of the right people. Once we get it, there's a whole separate discussion about how to get it widely supported and implemented, but we would need to agree on what that should be first.
Right now, a proposal for something like the first requirement exists in the form of the Content Security Policy put forward by Mozilla. This allows for a security policy to be specified outside the page, as a header returned by the webserver. Primarily, it controls what sources third party content can be loaded from, and prevents ways of getting around that. Additionally, it allows for policy directives that control additional features of the browsing experience. Following our framebusting example, one could use the frame-ancestors directive to ensure that your site can't be framed (in browsers which support CSP) by malicious sites. No JS in the page or frame attempts from third-parties could say otherwise. CSP is pretty great, but...
Like many defenses, the attacks have moved on. If you look at the number of new attacks enabled by HTML5, or attacks using Flash/SilverLight, limiting scripting and 10 policy directives won't cut it (but provides significantly more capability than nothing). We need something more comprehensive, and more future proof. What I'd like to propose, in a very early state looking for feedback, is an extension to CSP, where we have a policy directive for every browser feature. This could be done as some sort of capability tree where either an "on/off/whitelist/blacklist" rule can be applied. For example, image the following depth-first view of a tree leg "external data -> css -> images -> background-image" At the highest level, we could provide a global white/black list of the origins of external data, or turn it off completely. The next level down, we could do the same for CSS only, or completely disable it if our site doesn't require it. Continuing down the tree until it is possible for us to provide highly-granular control of individual CSS directives specifically. Thus, once could create very simple policies, or more complex granular policies.
This would buy us two improvements to CSP as I see it. The first is that we could avoid a reactive update of CSP every time a new attack using functionality not catered for by CSP comes out. The second benefit, is that the potential "attack surface" for an application could be greatly limited. Imagine being able to profile your app and provide a specific policy enabling only the functionality required by your app. Any attacks requiring such functionality would fail.
For the second problem, there are far less advanced tools available. The closet to it are the new HTML5 <iframe> sandbox directives, but they fall way short. What we need is something that can apply to all third party content (much like CSP, image sources, javascript sources, style sources etc.), and that provides a granular capabilities model. For this we could use the same capability tree from above. We'd need to work out how a site-owner defined policy and third-party enforced policy would relate, but it makes sense that a site-owner should not be able to re-enable stuff when including it as third-party content that the external site-owner has set. If not, attackers could just disable anti-framebusting CSP in their frame. So, a site-owner would only be able to further disable functionality when including third-party content. This could comfortable fit into the exiting CSP proposal, which already allows policy directives to be applied per origin.
This would allow a site owner to enforce significantly more control over content she was serving from third parties. For example, content from an ad network could be limited to only the functionality required (e.g. a specific image source and inclusion method, and possible explicit JS functionality to allow the monkey to be punched) and any malware served through it would be fairly castrated. Likewise, one could include content like Google Analytics or the FaceBook like button, but prevent them from setting a cookie.
In summary, I am proposing a discussion be started on extending CSP to provide a more granular control and enforcement model and further extending it to allow the enforcement to extend to how a site-owner wants to include third-party content. I'm possibly being quite naive about all of this, and would love some feedback. Truthfully, I'm not sure what the next steps would be, but we need to invest more time into fixing the web, rather than just breaking it.