Sunday, November 20, 2011

One of the more astonishing facets of the web platform is the Referer header. Whenever you click a link from one web site to another, the request that fetches the web page from the second web site contains the URL of the first web site. This behavior causes both security and privacy problems:

Security. Despite copious warnings, developers often include secrets in URLs. For example, to prevent Cross-Site Request Forgery (CSRF), developers often use secret tokens, which have a nasty habit of leaking into URLs and then into Referer headers sent to other sites.

The principle of least astonishment tells us we should remove this "feature", but, unfortunately, we can't just remove the Referer header from the platform. To many people rely on the Referer header for too many different purposes. For example, bloggers rely on the Referer header to generate trackback links, but that's just the tip of the iceberg.

As a first step, I wrote up a short proposal for a mechanism web sites can use to suppress or truncate the Referer header:

One subtlety in the design is including the "always" option. The main reason to include this option is to make it easier for us to later block the Referer header by default. The always options gives sites an escape valve to turn the Referer header back on, if needed.

Monday, November 7, 2011

This week, the W3C Web Application Security working group held its first face-to-face meeting at TPAC, the W3C's annual technical meeting. The main topic of discussion was moving Content-Security-Policy (CSP) from an unofficial draft onto the standards track. I'm actually pretty excited about CSP now, but I wasn't always its biggest fan.

CSP has a bunch of features, but the core value proposition (in my view) is that web applications can whitelist where their scripts come from. The main drawback of this approach is that authors need to remove all inline script from their web application because the browser doesn't know whether an inline script is part of the application or whether it was injected as part of a cross-site scripting (XSS) attack.

Initially, I was skeptical about CSP for two reasons:

CSP has a bunch of functionality unrelated to mitigating XSS, which makes the feature more complicated than necessary. Because I'm a big believer in minimal viable products, my initial reaction was to remove all the extra functionality and focus on the core use case for the first iteration.

I was worried that removing all the inline scripts from a web application would be too hard because web applications use inline scripts frequently. Joel Weinberger, Dawn Song, and I even wrote a paper exploring that issue.

I still view those criticisms as fair, but I worry less about those issues. By and large, the early adopters I've worked with have been able to use CSP effectively, which is some evidence that the extra complexity isn't the end of the world. I've also now built and retrofitted a number of non-trivial web applications to avoid inline script. It's a fair amount of work, certainly, but not an insurmountable task.

Thanks to some great work by Thomas Sepez, Chrome now uses CSP in the vast majority its HTML-based user interfaces. Over the years, there has been a steady trickle of XSS vulnerabilities in these interfaces, which is problematic because these interfaces (such as the browser's settings interface) have powerful privileges. Now that Chrome uses CSP extensively, we can be confident that we've mitigated this entire class of vulnerabilities.

My perspective on CSP now is that it makes a serious dent in one of the biggest problems in web security. It's definitely not a silver bullet (nothing ever is), but we should invest in CSP because we should be working on the big problems. If we're not willing to dream big, we should just pack up our tent and go home.