HSTS is a great way of protecting visitors to your website by ensuring their browser only uses a secure connection to communicate. If you use shared hosting and don't have access to change the header configuration, or you simply want to test HSTS without enabling it site wide, you can set the HSTS header in PHP.
Introduction
My blog post on HSTS provides a lot of information on exactly what HSTS is and how it works. I also wrote an article explaining how a user can manually add a HSTS Host in their browser. Enabling the HSTS header in PHP provides an opportunity to test HSTS on your site whilst limiting the exposure. I realise that there shouldn't really be anything to test as such, if you enforce https:// with a 301 redirect then it should work out of the box. Still, I like to give things a try before I buy!
Setting The HSTS Header
To test HSTS I created 2 PHP files called enableHSTS.php and disableHSTS.php and opened them up my text editor. All you need to do is ensure the call to header() occurs before any other output and use the following code:
enableHSTS.php
<?php header("strict-transport-security: max-age=600");
echo "<b>HSTS Enabled!</b>";
disableHSTS.php
<?php header("strict-transport-security: max-age=0");
echo "<b>HSTS Disabled!</b>";
That's it! You can now save and upload the files to your host and navigate to them to enable or disable HSTS for your domain. If I were to upload it to the /HSTS folder of my web directory I would simply need to navigate to https://scotthelme.co.uk/HSTS/enableHSTS.php and my browser would detect the HSTS header and flag the site as a HSTS Host. Make sure when you access the page that you do so using https:// as HSTS Headers will be ignored when sent over http:// for security reasons. You also need to ensure that your browser is HSTS compliant. Then if it causes any problems for you you can either wait 10 minutes for the max-age directive to expire or navigate to the disableHSTS.php file to immediately expire the policy. There's also the option of manually removing the host as a HSTS host directly in Google Chrome by visiting chrome://net-internals/#hsts. The benefit of this approach is that the HSTS headers will only be sent to browsers that navigate to the created PHP files directly and no one else.
That's how you issue HSTS Policy in PHP! You can visit my test pages located at https://scotthelme.co.uk/HSTS/enableHSTS.php and https://scotthelme.co.uk/HSTS/disableHSTS.php to see them in action. (These links are now disabled)
Why Do It In PHP?
Enabling HSTS in this way allows you to target specific users before enabling the feature site wide. You can test to see if flagging sub-domains will cause any unforeseen problems and have the option to either wait out the policy max-age or disable/remove the policy if you choose. I realise you can just navigate the site using HTTPS to test this out but for those like me, who like to test things out first anyway, it's a handy way of doing it on a small scale.Enabling HSTS like this is also a great solution for when you don't have access to the server config like on a shared hosting package. If you can't set a HTTP response header in the server config then setting it in PHP allows you to issue HSTS policy where you previously may not have been able to do so.
I'd be interested to hear thoughts and opinions on this approach and if anyone has suggestions on how to better implement it or perform the same task in other languages.