44

I had a Rails application with config.force_ssl = true, but now I dont want SSL encryption, but my app is still redirecting to https. I read this is a HTTP Strict Transport Security problem on Apache. How can I disable it?

rene
  • 41,474
  • 78
  • 114
  • 152
Phifo
  • 428
  • 1
  • 4
  • 8
  • this article might help [How does HTTP Strict Transport Security (HSTS) Work?](https://devedium.com/how-does-http-strict-transport-security-hsts-work-ea107ece28f2). You might need to remove it from your browser locally, also, make sure server not send the header Strict-Transport-Security. – liuhongbo May 10 '23 at 11:01

5 Answers5

75

It's not a problem with Apache, but with the fact that Rails sends an HSTS header.

In Chrome, you can clear the HSTS state by going into about:net-internals, as described in ImperialViolet: HSTS UI in Chrome. You may also have to clear the cache, since config.force_ssl = true also uses a 301 (permanent) redirection.

In addition, according to this answer, you could also make your application send an STS header with max-age=0. In your controller:

response.headers["Strict-Transport-Security"] = 'max-age=0'
Community
  • 1
  • 1
Bruno
  • 119,590
  • 31
  • 270
  • 376
  • 7
    It should be documented that once you enable the 'force_ssl' option in Rails, the only way to disable it is to have all your visitors clear their browser cache. :( – Joe Van Dyk Aug 30 '12 at 21:48
  • 11
    If this wasn't the case, you'd be vulnerable to SSL stripping which is what HSTS is designed to mitigate. Nothing to do with Rails. – Ali Nov 06 '13 at 16:00
  • it would be worth mentioning for developers though :) Thanks for this answer @Bruno – Stefan Hendriks Jan 10 '14 at 11:00
  • 1
    It's in the HSTS-specs: http://tools.ietf.org/html/draft-ietf-websec-strict-transport-sec-11#section-11.1 – TheConstructor Feb 12 '14 at 10:46
  • The only method for Firefox browser to clear HSTS caches: in your Profile folder find and open the file SiteSecurityServiceState.txt. This file contains cached HSTS and HPKP (Key Pinning, a separate HTTPS mechanism) settings for domains you have visited. It may be very disorganized. Search for the domain you want to clear the HSTS settings for and delete it from the file. Each entry beings with the domain name. Delete the entirety of the entry from the beginning of the desired domain name to the next listed domain. – Farside Apr 13 '21 at 12:57
17

Just wanted to point out @Bruno's answer and @JoeVanDyk's suggestions are true and can be applied beyond the context of Rails/Apache. I'm using PHP and Nginx. PHP has nothing to do with it in my case, but here's the steps with Nginx:

//sorry here's the nginx.conf part first, can't figure out how to mix multi-line 
//code with an ordered list

server {
   #...
   #change:
   # add_header  Strict-Transport-Security "max-age=315360000; includeSubdomains";     
   #to:
   add_header  Strict-Transport-Security "max-age=0;";
   #...
}
  1. clear your "browser history". To clarify on @JoeVanDyk's suggestion , I think you need to clear "browsing history" because clearing the cache didn't work for me (tested on Chrome/Firefox, please add comments if you know more).

  2. nginx.conf file (see code above)

  3. restart server

    root@ip-xxx-xxx-xxx:~# /etc/init.d/nginx restart.

After this, you can revert the nginx add_header Strict.. command to what you previously had. Just make sure you repeat steps 1-3 again.

tim peterson
  • 23,653
  • 59
  • 177
  • 299
  • 2
    I should add that you shouldn't need to restart, but rather reload. E.g. `/etc/init.d/nginx reload` – Matej Sep 04 '14 at 12:56
3

I found I couldn't delete an HSTS entry in Chrome as I was using an IP address for development. I couldn't seem to get chrome://net-internals/#hsts to delete the entry. I found that Chrome stores the entries in ../AppData/local/Google/Chrome/User Data/Default/TransportSecurity so I just deleted the file. It of course removes all HSTS requests, but I suspect they will be rebuilt over time.

pzupan
  • 169
  • 1
  • 7
2

Figured id offer a bit of thought on this. Setting cache time to 0 is a best bet and if you turn it off you need to leave it at 0 for weeks to clear out clients browsers. If you just need to clear HSTS in chrome (for your own browser) you can use chrome://net-internals/#hsts in the address bar to clear the cache for your site at your specific browser. Combined with the below "doorway" it becomes useful.

You can set temporary HSTS modes by setting/spoofing a custom header => key. Basically if a special request header exists, and it matches a key, set HSTS with a cache time of whatever you need. This would allow you to turn on or shut off HSTS for all traffic but you. Useful for trying HSTS out before you globally enable (to make sure all assets are loading). Also useful if you wanna temporarily clear out client cache while something is repaired (leaving you room for test).

dhaupin
  • 1,613
  • 2
  • 21
  • 24
  • How do you set the "cache time"? There's not an option at `chrome://net-internals/#hsts` – Pacerier Nov 06 '15 at 10:52
  • @Pacerier Ah chrome can clear the HSTS but it cant set cache time. Cache time comes from the origin/site HSTS header. Part of it may look like so: `strict-transport-security:max-age=15552000`...basically you need it to say `strict-transport-security:max-age=0` in order to disable HSTS for clients and wipe out their redirects (or, allow them to connect with invalid SSL). – dhaupin Nov 06 '15 at 16:56
  • But how could the user himself edit it on the client side? – Pacerier Nov 08 '15 at 00:42
  • @Pacerier hmm, I'm not sure you could short of hijacking the response from the website before the browser gets ahold of it, and including/spoofing that header. Honestly i have never experimented with it, but it could be feasible with some tool, maybe? – dhaupin Nov 08 '15 at 03:42
2

If you are developing an application/site and for any reason you choose to use the domain .dev or .app for it and if you are using Chrome, Edge (Chromium based) as your browser you won't be able to get rid of this error because Google bought TLD .dev and .app and force the use of HTTPS for those domain.

The "so called" workaround here is that you should change .dev or .app for something else, let say .local.

Hope this helps, somehow.

Ignacio
  • 61
  • 1
  • 3
  • very nice catch! that solved my problem since for some reason I always use .dev extension on my local development environments. switching to another extension such as *.test solved the issue. – spetsnaz Apr 23 '23 at 00:16