10

I've set up a Vagrant box with Ubuntu 18.04 and installed Apache 2.4.29. I've created and enabled a new conf file that looks like this:

<VirtualHost *:80>
    ServerName django.dev
    ServerAlias www.django.dev
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

For some reason, apache responds with an HSTS header when I try to call django.dev:

HSTS response header

I have no idea where this is coming from. There is no such header set in apache2.conf nor in 000-default.conf and I don't even have mod_ssl enabled.

Strangely enough, everything works as expected if call the IP directly. If I ping django.dev it is resolved to the exact same IP.

Does anyone know how or where I can disable HSTS? I'm at a loss and already wasted hours trying to solve this issue.

simon
  • 211
  • 2
  • 5
  • 1
    Using a domain registered to someone else is pretty much guaranteed to not end well. If you want to use .dev you should consider buying your own. Otherwise you can use .local, .test or .invalid none of which are resolvable on the global Internet (though names in .invalid are expected to not work, so it's really only good for testing certain failure scenarios). See RFC 2606 and RFC 6761, and also RFC 6762 for other special considerations regarding using .local. – Michael Hampton Apr 12 '20 at 05:19

1 Answers1

13

The HSTS policy is cached by the browser for the seconds specified in the max-age directive (RFC 6797, 6.1.1). Removing the header from web server configuration doesn't remove the policy from the cache (nor a preloading list, if submitted to one), and therefore it continues causing 307 Internal Redirects on every browser that has already cached the policy.

As specified in RFC 6797, 5.3:

Only the given HSTS Host can update or can cause deletion of its issued HSTS Policy. It accomplishes this by sending Strict-Transport-Security HTTP response header fields to UAs with new values for policy time duration and subdomain applicability. Thus, UAs cache the "freshest" HSTS Policy information on behalf of an HSTS Host. Specifying a zero time duration signals the UA to delete the HSTS Policy (including any asserted includeSubDomains directive) for that HSTS Host.

Therefore, the only way to remove an HSTS policy is to set an HSTS header with a zero duration, and the browser must also see this header on a secure connection without any TLS errors nor warnings (2.2).

<VirtualHost *:443>
    . . .
    Header always set Strict-Transport-Security "max-age=0"
</VirtualHost>

Strangely enough, everything works as expected if call the IP directly.

This is not strange at all. As explained in the Appendix A,

  1. HSTS Hosts are identified only via domain names -- explicit IP address identification of all forms is excluded. This is for simplification and also is in recognition of various issues with using direct IP address identification in concert with PKI-based security.

You can't disable HSTS on .dev

If this is literally a .dev domain, you can't disable HSTS.

Your security is our priority. The .dev top-level domain is included on the HSTS preload list, making HTTPS required on all connections to .dev websites and pages without needing individual HSTS registration or configuration. Security is built in.

Esa Jokinen
  • 43,252
  • 2
  • 75
  • 122
  • 1
    How stupid... `.dev` indeed was the problem. I wasn't even aware that this is an official TLD. Changing it to something else fixed the issue. Thanks! – simon Apr 11 '20 at 11:09
  • 3
    Never try and invent own TLDs! If they aren't in use currently, they may be in the future. – Esa Jokinen Apr 11 '20 at 11:11
  • 1
    It is not only `.dev` but many of the new Google TLDs, as they did add them to the HSTS preloading list. So it is the same for `app`, or for `new` that will come out later this year. – Patrick Mevzek Apr 11 '20 at 22:24
  • RFC 2606 "Reserved Top Level DNS Names" gives you the names to use as TLDs, in summary, `example` or `test` as TLD will always be fine (stay away from `local`). You can also register any domain name in any TLD and then use it as suffix for all your naming needs. There was also a discussion to allow the practice of using 2 letters code specifically set aside for user needs by ISO, like `zz`, but it is not written yet as a standard, see https://datatracker.ietf.org/meeting/106/materials/slides-106-dnsop-sessa-draft-arends-private-use-tld for example (and I personally think it is a bad idea) – Patrick Mevzek Apr 11 '20 at 22:28
  • @simon I've run into local development problems so many times that I always use site.example.com as a local development domain now – jdog Apr 11 '20 at 23:28
  • That HSTS header trick worked for me. Tell me -- can this work in an .htaccess file as well? – ServerChecker Aug 12 '20 at 04:08
  • The [`Header` Directive](https://httpd.apache.org/docs/2.4/mod/mod_headers.html#header) can be used in contexts: "server config, virtual host, directory, .htaccess". This means you could add the header using `.htaccess`, but as the HSTS header affects the hostname, the virtual host context is the most reasonable place for it. Also read [When (not) to use .htaccess files](https://httpd.apache.org/docs/2.4/howto/htaccess.html#when). – Esa Jokinen Aug 12 '20 at 05:39