HSTS Preload differing results - apache

On one of my sites I have Header set Strict-Transport-Security "max-age=31536000" env=HTTPS and this was enough for HSTS to be preloaded but the exact same snippet in my .htaccess file doesn't allow preloading on another site. I've went with Header set Strict-Transport-Security: "max-age=31536000; includeSubDomains; preload" env=HTTPS which fixed the issue but I'm wondering why the shorter version worked and preloaded a the first site but not the second?
Any insight would be appreciated.

why the shorter version worked
The short version couldn't have "worked". It would have been sufficient to implement HSTS, but not to have been accepted for the HSTS preload list.
Something else in your config must have been sending the complete header.
The only way to confirm what is actually going on is to record the HTTP request/response headers being sent on the request, not by the directives in your (.htaccess?) config file.
Even the directive you posted is not necessarily sufficient by itself. You must have something that is setting the HTTPS environment variable (this is not the same as the HTTPS server variable). And if you have canonical redirects from www to non-www (or vice versa) then you are missing the always argument to set the header on the 301 redirect (HTTPS only) - which is also a requirement of the "preload list".
It is far easier and less prone to error to implement HSTS "preload" in the server config. If you only have access to .htaccess then I would be hesitant to go for "preload list" submission.
See also my answer to the following related question on CodeReview SE:
https://codereview.stackexchange.com/questions/250805/hsts-recommendations-in-htaccess

Related

Strict-Transport-Security influence on http reverse proxy that redirects to https

The server response comes with HSTS header, and since I'm using reverse proxy HSTS header is also being sent through proxy response.
Since there are different domains (proxy and server) does HSTS make the browser automatically change the schema from http://proxyhost.com to https://proxyhost.com? or the preload list will call automatically https://serverhost.com when the user will request http://proxyhost.com?
does HSTS make the browser automatically change the schema from http to https
Indeed! and since:
a reverse proxy HSTS header is also being sent through proxy response.
... the configuration of a reverse proxy can involuntarily make your domain set theHSTS header.
Took some while to see why my apache server sets the HSTS header - for I hadn't configured that in the apache web server. It was due to a ReverseProxy: as the foreign domain sets theHSTS header this header comes then (reverse proxy!) with my domain's name. This was then propagated to the client's browser which stores it. Thus, all my domain's sites (and in this case also all my subdomains!) where forced to use https (not when using e.g. curl of course, but firefox, chromium etc.).
Thanks for your question - it was already the perfect direction!
In my case I simply could use aRewriteRule instead of a reverse proxy :) but this of course depends on your scenario.
You also gave the proper answer in your comment:
in this case I should unset HSTS header in the reverse proxy
Right! Just add Header unset Strict-Transport-Security directly after the ProxyPassReverse directive, and you can use a reverse proxy without inherit the HSTS header.

Apache Server: Redirection via http headers

I am trying to force browser to use https even when the user enters http URL. The idea is to use http response headers from the server. I am able to implement redirection using redirect (in site.conf) & Rewrite (which is disliked universally) but want to test out this method too.
Now I have tried adding the the following to my /etc/apache/sites-enabled/mysite.conf but despite the browser receiving the header response the user is not redirected to https (default apache page is shown):
Header set Location https://www.example.com/
Header set X-Forwarded-Proto: https
Header set Strict-Transport-Security "max-age=180; includeSubdomains"
Do I have to change anything else in the apache configuration to achieve this? (all modules are correctly loaded)
The Location header is only used for redirect responses (with a HTTP response code of 3XX) or Created responses (with a HTTP response code of 201):
https://www.rfc-editor.org/rfc/rfc7231#section-7.1.2
Just setting the header on a random page will not make the browser redirect.
When you use apache Redirect and Rewrite rules they set the response header AND add the location header. I really don't know why you'd want to do this manually.
And rewrite is not "universally disliked". It just overused when redirect would be simpler and more efficient in a lot of cases. If you need something more complicated then Rewrite is the right tool to use.
Finally you should not sent the Strict-Transport-Security header on a HTTP response (and the browser will rightly ignore it you do) but only on a HTTPS responses.

Putting hsts headers in apache using htaccess or httpd.conf

I have purchased a ssl certificate recently and have redirected all my traffic on secured https way but i want to get included in hsts preload list. For that reason i want to include hsts header. Is there any way using .htaccess or httpd.conf or if there is another way then please tell me in detail
you can set the hsts header in a .htaccess file:
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" env=HTTPS
#see How to set HSTS header from .htaccess only on HTTPS for more information
or with php:
header('Strict-Transport-Security: max-age=63072000; includeSubdomains; preload');
Also you can put HSTS header on application side, I mean PHP. Add following code top of your header.php or index.php
<?php header("strict-transport-security: max-age=600");
People who uses shared hosting does not have an access to apache.conf. So proper way to do this is putting it on apache.conf.

problems using mod_headers with php-fpm/mod_fastcgi

I'm trying to add HSTS headers to every response, across my app.
My first thought was to use mod_headers — I placed this directive in an .htaccess file at the documentroot:
Header set Strict-Transport-Security "max-age=7776000"
This works fine on my local setup using Apache 2.2 and mod_php. All resources respond with the appropriate HSTS header.
My deployment environment uses Apache 2.2 and mod_fastcgi and the above technique works for any resource except php files.
Another SO question had a similar problem, where incoming requests (?) had headers stripped — but I'm concerned about modifying headers of response leaving the server.
How can I add response headers to php resources in the context of an .htaccess file?
According to the docs for mod_headers you probably need to set the optional conditional flag for the header directive.
So in this case, it would become
Header always set Strict-Transport-Security "max-age=7776000"

Unset or Expire HSTS Policy on Apache Server

I set this line in a ssl vhost on my server. I am running Apache 2.x
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"
This was a major mistake, because now I want to remove it and force users back to http pages sometimes. It was not enabled for very long, but I don't want to lose anyone. If I try to force users back to http pages right now they end up in a redirect loop.
How can I unset or expire HSTS using settings on the server so that when users do visit the site and hit the https version of the site the Strict-Transport-Security setting is removed from their browser and they are able to be redirected to http?
I already know I made a dumb mistake. I learned a lesson and just need to clean it up now.
Figured it out:
NOTE: A max-age value of zero (i.e., "max-age=0") signals the UA to
cease regarding the host as a Known HSTS Host, including the
includeSubDomains directive (if asserted for that HSTS Host).
See also Section 8.1 ("Strict-Transport-Security Response
Header Field Processing").
From the RFC 6797 document.
So, I will just set the following line and leave it for a few months before removing it.
Header always set Strict-Transport-Security "max-age=0; includeSubDomains"