Playing with Referer Header
There are two situations in which you would want to control the Referer
header. By the way, Referer
is a miss-spelling of the word "referrer".
If you want to control your personal browser not to pass the Referer
to site2.com
, you can do that with many browser extensions:
- For Firefox there is RefControl (which I use and am happy with. I use the option "Forge- send the root of the site")
- Chrome has Referer Control
The other situation is where you are a webmaster and you want the users of your site (site1.com) not to send the Referer
to other sites linked on your site. You can do that in multiple ways:
- Use SSL/TLS (https) on your site and a security feature of the browser is not to pass the
Referer
to HTTP links on your pages served up with SSL/TLS. However, if the links on your pages use HTTPS, thenReferer
will still be passed over unless explicitly turned off by other means described below. - Use the HTML5
rel="noreferrer"
attribute. It is supported by all major browsers. - Use a Data URL ('data:') to hide the actual page the link is coming from:
<a href='data:text/html;charset=utf-8, <html><meta http-equiv="refresh" content="0;URL='http://site2.com/'"></html>'>Link text</a>
. - Hide the
Referer
by redirecting through an intermediate page. This type of redirection is often used to prevent potentially-malicious links from gaining information using theReferer
, for example a session ID in the query string. Many large community websites use link redirection on external links to lessen the chance of an exploit that could be used to steal account information, as well as make it clear when a user is leaving a service, to lessen the chance of effective phishing.
Here is a simplistic redirection example in PHP:
<?php
$url = htmlspecialchars($_GET['url']);
header( 'Refresh: 0; url=http://'.$url );
?>
<html>
<head>
<title>Redirecting...</title>
<meta http-equiv="refresh" content="0;url=http://<?php echo $url; ?>">
</head>
<body>
Attempting to redirect to <a href="http://<?php echo $url; ?>">http://<?php echo $url; ?></a>.
</body>
</html>
As of 2015 this is how you prevent your website from sending the Referer header:
Just add this to the head section of the web page:
<meta name="referrer" content="no-referrer" />
This works both for links and for Ajax requests made by JavaScript code on the page.
Other valid meta
options include:
<meta name="referrer" content="unsafe-url" />
<meta name="referrer" content="origin" />
<meta name="referrer" content="no-referrer-when-downgrade" />
<meta name="referrer" content="origin-when-cross-origin" />
• See if it works for your browser here: http://caniuse.com/#feat=referrer-policy
• See specs here: http://w3c.github.io/webappsec/specs/referrer-policy/
Note: If you want to remove the referrer by using JavaScript only, I believe you could add the appropriate meta tag dynamically just before making the Ajax request. I have not tested this, however.
Also note that browsers now send the Origin
header which includes domain and port, and, as far as I know, cannot be removed. If you use <meta name="referrer" content="origin" />
the referrer will contain
similar information to the Origin
header, which is already good from a privacy point of view, since it will hide the exact page the user is in.
You can't modify the referer header unless you control the calling client, e.g. the browser.
Browsers block modifying the referer, and server-side code can't inject headers into a request as there is no way to get the header from the server to the client, and make the client inject it into the referer header of it's next request.
That's assuming the browser doesn't have a particular vulnerability around header injection from JavaScript though.