ISSUE MIGRATED FROM https://gitlab.com/aegir/hosting_https/issues/35 (see #2934484: Move back issue management to D.o)

mlutfy @mlutfy commented 7 months ago

Discussed with Colan:

Since the use-case for "I want https required now, but not tomorrow" is a marginal use-case, it's safe to assume that when "https=required", we can add HSTS headers. It's a sane default.

Colan recommended to add in https://gitlab.com/aegir/hosting_https/blob/master/submodules/nginx_http... (+ equivalent for Apache).

However, in nginx, add_header must be called again if a location block added headers. Therefore, for nginx, this means we would need the add_header to be called in ~/config/includes/nginx_vhost_common.conf:

location = /index.php {
[...]
add_header Cache-Control "no-store, no-cache, must-revalidate, post-check=0, pre-check=0";
add_header Strict-Transport-Security "max-age=15768000";
[...]
}

I suspect it would also be required for the @cache and @drupal location blocks.

Can this be done with a variable?

@memtkmcc Any thoughts?

Adam Andrzej Jaworski @memtkmcc commented a month ago

It belongs only in the /index.php location, and should be doable, since add_header works also within if in the location:

Syntax: add_header name value [always];
Default: —
Context: http, server, location, if in location

But, it should be optional, and not set by default, because otherwise disabling/enabling HTTP->HTTPS redirection via Required/Enabled in the control panel will confuse people.

I mean, in real life people tend to set "Required" instead of "Enabled" encryption from the beginning, without thinking about consequences (like, LE will not generate the working cert because some alias has no valid DNS record, etc.) and then they will lock themselves in the not working HTTPS mode due to HSTS already added and sent.

Making it default for "Required" mode is too optimistic approach. We need to take into account typical user error, and starting with "Required" without understanding what may happen is pretty common.

Comments

helmo created an issue. See original summary.

bgm’s picture

> But, it should be optional, and not set by default, because otherwise disabling/enabling HTTP->HTTPS redirection via Required/Enabled in the control panel will confuse people.

I soft-disagree with this. We're making it more complicated/crippled for 95% of people. If someone activates https by mistake then HSTS gets enabled, they just need to go in their history and click "forget this site".

There's only the use-case where someone wants https, accidentally enabled "https=required", then later decides that they actually wanted it to be "https = enabled". In that case, they can set a HSTS header to force-expire it. And still, people who do mixed http/https deserve the extra hurdles. We need to make it simpler for people who run standard recommended configurations, i.e. always-https with HSTS.

That said, I haven't found a clean/decoupled way to implement HSTS in nginx:

In `http/Provision/Config/Nginx/Inc/vhost_include.tpl.php`, I added:

map $https $hosting_https_hsts {
  default '';
}

and then in location index.php {} of vhost_include.tpl.php:

 add_header Strict-Transport-Security $hosting_https_hsts;

then hosting_https can set the variable in the vhost server block:

set $hosting_https_hsts "max-age=15768000";

it's what I ended up doing in https://github.com/coopsymbiotic/provision_symbiotic/, but I haven't found a better way to decouple it.

  • helmo committed 500de9a on 2936046-hsts
    Issue #2936046: Add Strict Transport Security to HTTPS-only sites
    
helmo’s picture

Status: Active » Needs review

I've just pushed a 2936046-hsts branch to add this. nginx is untested but straight from https://github.com/mlutfy/provision_sts

bgm’s picture

It doesn't work for nginx (c.f. above comments, the header needs to be added in the location block for index.php), but seems OK for Apache.

colan’s picture

Status: Needs review » Needs work
helmo’s picture

I've added this as a must have for 3.17 ... could you find some time to fix the nginx part?