I redirect all my websites from HTTP to HTTPS with:
<VirtualHost *:80>
ServerName example.com
RewriteEngine on
RewriteCond %{HTTPS} !on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
</VirtualHost>
<VirtualHost *:443>
ServerName example.com
DocumentRoot /www/example.com
SSLEngine on
...
</VirtualHost>
I notice that, when navigating from a site anothersite.com
and
-
clicking on a link to https://example.com, Javascript’s
document.referrer
works and givesanothersite.com
-
clicking on a link to http://example.com, Javascript’s
document.referrer
is empty!
How to prevent document.referrer
to vanish when using a HTTP->HTTPS redirection via Apache?
Or should I do the automatic HTTP->HTTPS redirection with another method to keep the referrer
?
2
Answers
The referrer header is sent by the browser, and apparently a new request doesn’t carry the header from 2 requests ago.
As it’s up to the browser to send this header or not, you only have limited options – and I can’t even guarantee that it’ll work:
Utilize HSTS by adding
(or similar – pick values that you like) to your https virtual host. Then you’ll still miss the first redirected referrer, but anybody coming back within a year (63072000 seconds) will connect on https right away.
Careful: If you offer anything on http (only), it’ll be unavailable to any browser that has ever seen (and honors) the HSTS flag.
Also, there are many cases (and they changed in history, based on discovered vulnerabilities), in which the header is sent or not – with numerous articles that shine some light on all the conditions that cause the header to appear or disappear.
Check, then double check, if you’re falling into one of the categories that can be omitted. You can’t assume that the header is there in the first place.
As stated in this answer, it is up to the browser to send the Referrer back after a redirect. And apparently, it does not.
However, you can write your rule like this and read the referrer from query if it does not exist in headers.
Note that a user can always spoof referrer. But this method will make it easier to spoof it. Depending on your use case, this solution may be a security issue for you.
Correction
According to this answer the referrer will be empty when user:
Additional information in HTTP specs.