Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement HTTP Strict Transport Security (HSTS) on AWS Elastic Load Balancer?

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?

like image 652
Pedreiro Avatar asked Oct 30 '17 22:10

Pedreiro


People also ask

How do I enable HTTP Strict Transport Security HSTS?

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.

How do I fix missing HTTP Strict Transport Security policy?

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.


2 Answers

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.

like image 151
eklingen Avatar answered Oct 29 '22 03:10

eklingen


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"
like image 22
Pedreiro Avatar answered Oct 29 '22 03:10

Pedreiro