skip to Main Content

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 gives anothersite.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


  1. 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

    Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"
    

    (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.

    Login or Signup to reply.
  2. 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.

      RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}?referrer=%{HTTP_REFERER}
    

    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:

    switches from a https URL to a http URL.

    Additional information in HTTP specs.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search