Odd HSTS Behavior
While testing an app with an invalid cert (internal CA), I noticed some interesting behavior with HSTS and Firefox. The browser was ignoring an aspect of the HSTS RFC after an invalid cert was accepted.
Before that a bit of background..
HSTS is HTTP Strict Transport Security. It is a header passed from the server/application to the user. It tells the browser to only connect to the site over HTTPS. Even if the user explicitly types http://example.com if the site has sent an HSTS header (or it’s preloaded) the browser will upgrade the connection to HTTPS.
So while testing this app I followed this flow
- Access site while proxying traffic with trusted cert with Burp Suite
- The browser sends back an HSTS header telling the browser to upgrade connections
- I can browse the site normally
If I disable the intercepting proxy I’ll get a cert error as expected. Interestingly, I do not have the option to access the site by adding an exception. Due to the site having HSTS enabled as seen below.
This is because Firefox has already received the HSTS header from the server. As outlined in the HSTS RFC, if HSTS is enabled the browser should not allow the user to access the site and Firefox does not allow you to add an exception.
This is expected behavior as it’s outlined as part of the HSTS RFC.
What I find interesting is that, although not allowing an exception when a bad cert and HSTS is a good security practice, it is not enforced by the browser. I believe it would only be enforced if the site was using HSTS preloading so the user has no chance to add an exception. I would assume that once the user adds an exception for the cert the browser would still enforce the HSTS restriction that does not allow bad certs. From my limited testing Chrome also has the same behavior.
With the proliferation of HTTP security headers, the trade off between ease of use and enforcing RFC presents interesting behavior.