Search code examples
apache.htaccesshttp-redirectmod-rewritehsts

HSTS and redirection


I was testing my website here https://hstspreload.org and I got this error:

Error: HTTP redirects to www first

http://example (HTTP) should immediately redirect to https://example (HTTPS) before adding the www subdomain. Right now, the first redirect is to https://www.example. The extra redirect is required to ensure that any browser which supports HSTS will record the HSTS entry for the top level domain, not just the subdomain.

As far as I can understand, the redirect, to be valid, should be done this way:

  1. http://example (this is what the user enters in the address bar)
  2. https://example (first redirect, to HTTPS)
  3. https://www.example (second redirect, to subdomain www)

At the moment, this is my htaccess code causing the redirect:

RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.example.com/$1 [R,L]

Is it possible/advisable to insert another redirect here? Are there any risks?

Any comment/advice/suggestion/rotten-tomato is appreciated :-)


Solution

  • Summary of the comments:

    • Configuration in httpd.conf and .htaccess is read top to bottom.
    • For RewritRules, they are applied in sequence, top to bottom, until you reach the last one. All rules that match the condition are applied.
    • To prevent that, you can add the [L] tag to a RewriteRule. This tag says to Apache that it was the last rule to apply if it matches the conditions. All further rules are ignored for this request.

    The sequence of rewrites here is:

    1. the client requests http://example.com
    2. A RewriteRule redirects the client to https://example.com
    3. The client comes back with https://example.com
    4. A second RewriteRule redirects the client to https://www.example.com
    5. The client comes back with https://www.example.com
    6. No Rewriterule applies, Apache responds to the request.

    Why do it this way? It covers all cases. If a client's first request is already https://example.com, the scenario above will start at step 4.

    A sample configuration could look like:

    Listen *:80
    <VirtualHost *:80>
        ServerName example.com
        ServerAlias www.example.com
    
        RewriteCond %{HTTPS} !=on
        RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
    
        [... OTHER CONFIGURATION ...]
    </VirtualHost>
    
    Listen *:443
    <VirtualHost *:443>
        ServerName example.com
        ServerAlias www.example.com
    
        RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
        RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
    
        [... OTHER CONFIGURATION ...]
    </VirtualHost>