Thursday 23 February 2017

Making WCG Online secure

I'm going to talk about one of my projects - WCG Online.  This project has been online for a couple of years, and it's designed to give you, a valued member of the World Community Grid community, access to some more detailed statistics, as well as some lovely pretty graphs.  I'm hoping to add more functionality soon as well, but for now, that's the gig.

As the internet is slowly but surely turning secure (HTTPS instead of HTTP - check your address bar now!), and this site takes your username and verification code to get your stats - not the end of the world as it's certainly not your password and can only be used to view information, but still, best to be secure.

Having purchased (unfortunately my shared hosting package doesn't support Let's Encryptand installed my certificate, it was possible to access the site via HTTPS - excellent start!  But what about people who have already bookmarked the site as HTTP, or they happened to search for "wcg online" on Google and clicked the first result, in which case they would still get the HTTP page.

Having looked around a bit, I decided the best thing to do would be to change my .htaccess file and create a rewrite condition, like this...

  <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{HTTPS} !=on 
    RewriteRule ^.*$ https://www.wcg.onl%{REQUEST_URI} [R=301,L]   
  </IfModule>

So this is checking if the "HTTPS" variable is not "on" (as in, it's off, therefore HTTP) and then the rule changes the base URL to be HTTPS with the original request URI (the page and query string).  The "R=301" returns a 301 HTTP status to the browser, which caches a permanent redirect, so the browser should always use HTTPS moving forwards.

Unfortunately this didn't work for me (I later discovered my shared hosting package uses the variable "ENV:HTTPS" instead!), and nor did a number of other suggested rewrite rules, such as checking port 80, which is typically used for HTTP.  I ended up adding the following PHP code into the main page of my site...

  if($_SERVER["HTTPS"]!=="on") {
    header("Location: https://www.wcg.onl",true,301);
    exit;
  }

This essentially does the same thing, but it's done within the PHP code, instead of by the webserver layer.  Again, this uses a 301 HTTP status to tell the browser to always use HTTPS.

To back this up, I then added the following header...

  Strict-Transport-Security: max-age=16070400; includeSubDomains

This uses HTTP Strict Transport Security (HSTS), which if you're not aware, essentially tells the browser that it should always use HTTPS for this site.  This means that the browser will now use a 307 Internal Redirect, which is much much quicker as it happens internally instead of hitting the server.

The unfortunate side effect of this is that the site will forget you, when you first switch from HTTP to HTTPS.  This is because the local storage that it uses to store this information, as no information is stored on the server, cannot be access cross-protocol.  I think this is a small price to pay for security though!

No comments:

Post a Comment