I would like to implement HSTS to my application.
I have an ELB terminating SSL and forwarding the traffic to my application, which is an apache server used as reverse proxy.
I know that in order to implement HSTS, I would need to add the header Strict-Transport-Security to my request.
Unfortunately, it seems that I cannot implement it on my Apache server as it would have to be added to the HTTPS Virtual Host and my Apache only has the http virtual host configured, since the SSL is terminated on the ELB.
That means that the ELB would have to add the header Strict-Transport-Security to the request when it pass it forward.
How do I do that? Can I add some sort of security policy that would do that for me?
Go to SSL/TLS > Edge Certificates. For HTTP Strict Transport Security (HSTS), click Enable HSTS. Set the Max Age Header to 0 (Disable). If you previously enabled the No-Sniff header and want to remove it, set it to Off.
Use your browsers developer tools or a command line HTTP client and look for a response header named Strict-Transport-Security. Access your application once over HTTPS, then access the same application over HTTP. Verify your browser automatically changes the URL to HTTPS over port 443.
If you're working with Apache 2.4+, you may be familiar with expressions and the directives <If>
, <ElseIf>
, and <Else>
.
I have a complex configuration between dev, staging, and production environments, so relying on the [L]
flag with the RewriteRule
just wouldn't cut it for me.
This brought me to the following solution, which I placed in my .htaccess:
<IfModule mod_headers.c>
<If "%{REQUEST_SCHEME} == 'https' || %{HTTP:X-Forwarded-Proto} == 'https'">
Header set Strict-Transport-Security "max-age=31536000"
</If>
</IfModule>
It works better in my environment and I feel that it is more reliable for meeting the RFC.
You could drop the "%{REQUEST_SCHEME} == 'https'
part if you never hit your instances directly, but that's part of my debug process in my dev environments.
Much thanks to Pedreiro for pointing me in the right direction for the actual specifications on the HSTS RFC.
I asked the AWS Support and the answer was that at the moment ELB cannot add HSTS headers on the requests from the clients. So, I decided to find a workaround using my Apache server. Here is the solution I found:
The HSTS RFC states that
An HSTS Host MUST NOT include the STS header field in HTTP responses conveyed over non-secure transport.
What I did then was to set the header AFTER the http=>https redirection in Apache. Since this redirection has the flag [L], that means that the 301 redirection will not include the header, but any https request will. My apache config looks like this:
<VirtualHost *:80>
...
#http=>https
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule . https://%{HTTP:Host}%{REQUEST_URI} [L,R=permanent]
#hsts
Header set Strict-Transport-Security "max-age=31536000"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With