Enabling HSTS in AWS ELB application load balacer

18,333

Solution 1

HSTS is a policy that is controlled by the backend and not by the load balancer. One could argue that AWS could enable this, but there are other issues that make this more complicated (violation of specs, permanent redirects for HTTP, etc.)

The issue with HSTS is that you cannot (should not) send Strict-Transport-Security over HTTP. The specs say to only send the header over a secure connection. HTTP is not secure. Since the load balancer is talking to the backend over HTTP, IIS is NOT sending the header. You need to use HTTPS on the backend to enable HSTS.

RFC6797

If your goal is to send "Strict-Transport-Security" to the client, use Layer 4 listeners on your load balancer and handle HTTPS at your backend. If a request arrives on HTTP, send a permanent redirect (301). Benefits include absolute control, improved HTTP/2, etc.

Another option is to change your listener to use HTTPS to talk to the backend. Setup HTTPS and SSL on the backend.

Solution 2

It sounds like this is the approach the OP used but for some reason the headers weren't passed. I just want to confirm this approach definitely does work and give additional details.

It is entirely possible to set the HSTS header on a backend server over HTTP. At the end of the day, it's just a header like any other and the server will happily send it.

However, what happens is that the BROWSER will ignore the HSTS header received on an HTTP response, as per the HSTS spec.

BUT, there is a way to make it work, firstly you configure your backend server to send the HSTS header.

Then, assuming the Application Load Balancer is listening on HTTPS, but your target group (and backend servers) are on HTTP, what happens is:

  • browser sends request to ALB over HTTPS
  • ALB forwards request to backend over HTTP
  • backend server sends the response including the HSTS header to the ALB over HTTP
  • ALB sends same response + header to the browser over HTTPS.

Therefore the browser receives the response and the HSTS header over HTTPS, and it will obey HSTS.

An argument against doing this is that you shouldn't send HSTS header over HTTP at all. However, the same argument applies to your whole website - no-one should be serving any websites over HTTP out to the internet. If you consider it safe to terminate HTTPS at the ALB and run the backend server on HTTP, then it's just as safe to send the HSTS header in the same way.


NOTE: If you're using HSTS then you've almost certainly got a redirect from HTTP to HTTPS in place. Bear in mind that the HSTS header will be sent with the redirect over HTTP, but the browser will ignore it. Once the redirect happens and the HSTS header comes over HTTPS, the browser will obey it.

Technically as per RFC6707 section 7.2, you shouldn't send the HSTS header back to the browser over plain HTTP. What you should do is make the setting of the header conditional, based on the X-Forwarded-Proto request header value.

Share:
18,333
Prasanna B R
Author by

Prasanna B R

Updated on June 15, 2022

Comments

  • Prasanna B R
    Prasanna B R almost 2 years

    We like to enable HSTS to our IIS deployed web application.

    We have SSL terminating ELB Application load balancer. We have enabled the URL rewrite module in IIS and configured the x-Forward-Proto tag to decide and enable HSTS header in the response.

    Presently, ALB does not appear to pass custom headers from IIS to the ALB, to the end-user. We wanted to see if there is a way to enable HSTS either at ALB level where it can accept custom headers or if it can be set at IIS level and ALB can pass through the HSTS headers to the browser?