9

I want to trial a HSTS policy on my blog without enabling it site wide initially. As a HSTS policy is just a HTTP response header would there be any problem with sending the header in PHP like so:

header("strict-transport-security: max-age=600");

The site will redirect any http:// request to https:// and I realise that this will likely result in the HSTS header being sent over http:// which it shouldn't. However, to be HSTS compliant a user agent should disregard HSTS policy delivered via http:// as it could have been maliciously injected. As this is only for testing purposes I'm not overly concerned anyway.

This will allow me to issue the header on a specific page only and expose it only to myself without affecting any other users. I could also have another page to disable the HSTS policy like so:

header("strict-transport-security: max-age=0");

Should this prove to be successful are there any issues that can be seen with issuing HSTS policy in such a way? Perhaps users on shared hosting or without access/knowledge to configure a response header could still implement HSTS in this way.

2 Answers 2

12

HSTS is enabled by returning the strict-transport-security header from a HTTPS response - the browser does not care whether this is set in PHP, by the server, or by a load balancer - as long as it receives a valid header over HTTPS then HSTS will be enabled.

You should be OK only returning this header from a single page for testing too. RFC 6797 states

If a UA receives HTTP responses from a Known HSTS Host over a secure channel but the responses are missing the STS header field, the UA MUST continue to treat the host as a Known HSTS Host until the max-age value for the knowledge of that Known HSTS Host is reached.

so your other responses without the header will not cancel HSTS for your site.

Setting max-age=0 is also the correct way to cancel HSTS for your site (per receiving user agent). The only thing I've spotted which is non-standard the way you are doing is that you are sending the header over HTTP also - although this would be ignored by a compliant user agent it is invalid so I would make sure to only transmit this when the connection is secure (best to stick to standards as close as possible I find).

You can check whether to emit the header with the following code that will check that the page has been accessed via HTTPS:

<?php
function isSSL(){
 
    if($_SERVER['https'] == 1) /* Apache */ {
        return TRUE;
    } elseif ($_SERVER['https'] == 'on') /* IIS */ {
        return TRUE;
    } elseif ($_SERVER['SERVER_PORT'] == 443) /* others */ {
        return TRUE;
    } else {
        return FALSE; /* just using http */
    }
 
}
?>
0
0

The HSTS header is for a domain (or subdomains, if supplied with the includeSubDomain directive). However, a value of 0 in max-age will cause the user agent to cease using HSTS. (Refer to section 6.1.1 of the draft spec.)

2
  • 1
    Yes I know :-) That's why I said "I could also have another page to disable the HSTS policy like so" The UA would stop treating the domain as a HSTS host once it received that header, effectively disabling HSTS for the domain. Oct 1, 2013 at 7:19
  • 1
    I don't see a reason why that setup won't work. Oct 1, 2013 at 9:00

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .