Sunday, November 20, 2011

Referer (sic)

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:
  1. 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.
  2. Privacy.  The Referer header is even worse for privacy, for example, leaking search terms from your favorite search engine to the web sites you visit.  As another example, Facebook accidentally leaked user identities to advertisers via the Referer header.
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:
<meta name="referrer" content="never">
<meta name="referrer" content="origin">
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.

This mechanism is now implemented in WebKit and will hopefully be implemented in Firefox and other browsers soon.

9 comments:

  1. It seems to me that the https behavior for always violates the least astonishment for developers.

    Additionally, not sure if this is a resource level property (thus implemented at the document) or a web application level property (thus implemented maybe via CSP that can be set by the web application admin).

    ReplyDelete
  2. Yeah, we'll probably want to add a directive to CSP to control this policy. That's probably something good to consider for CSP 1.1. Please feel encouraged to add it to this wiki page:

    http://www.w3.org/Security/wiki/Content_Security_Policy

    ReplyDelete
  3. Ironically, people also use Referer header fields to defend against CSRF.

    ReplyDelete
  4. Also, maybe spelling it correctly here (as opposed to the header field name) will cause unnecessary confusion... (maybe this is a case where both need to be allowed?)

    ReplyDelete
  5. Typically, we spell it correctly when we refer to it in the DOM. For example, noreferrer and document.referrer both spell it correctly.

    ReplyDelete
  6. Some people use it against hot linking.

    ReplyDelete
  7. I noticed that "never" and "always" answer to the question "when?", but "origin" answers to "what?".

    Shouldn't it be something like "none", "origin" and "full"? Or maybe "no", "yes" and "origin".

    ReplyDelete