From e6263250af9b4eb4135176175c6663a52f0e6021 Mon Sep 17 00:00:00 2001 From: Richard Towers Date: Mon, 14 Jun 2021 17:53:31 +0100 Subject: [PATCH] Redirect straight from http://gov.uk to https://www.gov.uk At the moment, requests to http://gov.uk are redirected to https://gov.uk and then to https://www.gov.uk. Why is it like this? -------------------- This was done deliberately because we wanted to get `gov.uk` in the HSTS preload list (which is a list of domains which browsers should always use HTTPS for). The Strict-Transport-Security header is ignored for plain http:// requests, so we needed to redirect to https://gov.uk to be able to serve the response in a way which would be respected by browsers. In the time since we added this redirect, `gov.uk` has been put on the HSTS preload list: https://github.com/chromium/chromium/blob/master/net/http/transport_security_state_static.json ``` { "name": "gov.uk", "policy": "custom", "mode": "force-https", "include_subdomains": false }, ``` Why should we change it now? ---------------------------- There's a theoritical web performance cost to the extra redirect. An extra TCP connection to gov.uk:443, and an extra TLS handshake for https://gov.uk, and an extra HTTP request. All of which we could have skipped if http://gov.uk redirected straight to https://www.gov.uk. This is mostly theoretical because gov.uk is on the HSTS preload list, so browsers won't make the first request (to http://gov.uk). This commit only changes the behaviour for the http:// redirect (the 801 virtual status code), so nothing will change for HSTS respecting user agents which never make http:// requests. User agents which don't follow HSTS (e.g. curl) will get a simpler redirect, which will be a little bit faster. Is there some risk of disaster here? ------------------------------------ We have to be very careful with gov.uk's HSTS status. There are lots of subdomain of gov.uk which still don't support https (including most of the domains we "transitioned"). Accidentally putting `gov.uk` on the HSTS preload list with includeSubdomains set would effectievly break all the http:// subdomains. This happened by accident in a version of IE in 2019 (due to a mistake on microsoft's side). This change should not increase the risk of that kind of issue - https://gov.uk will still serve the Strict-Transport-Security header, as it has since 2017. --- spec/test-outputs/tldredirect-integration.out.vcl | 3 ++- spec/test-outputs/tldredirect-production.out.vcl | 3 ++- spec/test-outputs/tldredirect-staging.out.vcl | 3 ++- spec/test-outputs/tldredirect-test.out.vcl | 3 ++- vcl_templates/tldredirect.vcl.erb | 3 ++- 5 files changed, 10 insertions(+), 5 deletions(-) diff --git a/spec/test-outputs/tldredirect-integration.out.vcl b/spec/test-outputs/tldredirect-integration.out.vcl index 03042098..7e7aa1bf 100644 --- a/spec/test-outputs/tldredirect-integration.out.vcl +++ b/spec/test-outputs/tldredirect-integration.out.vcl @@ -36,8 +36,9 @@ sub vcl_error { if (obj.status == 801) { set obj.status = 301; set obj.response = "Moved Permanently"; - set obj.http.Location = "https://" req.http.host req.url; + set obj.http.Location = "https://www.gov.uk" req.url; set obj.http.Fastly-Backend-Name = "force_ssl"; + # Strict-Transport-Security header is ignored for http:// requests } if (obj.status == 802) { diff --git a/spec/test-outputs/tldredirect-production.out.vcl b/spec/test-outputs/tldredirect-production.out.vcl index 03042098..7e7aa1bf 100644 --- a/spec/test-outputs/tldredirect-production.out.vcl +++ b/spec/test-outputs/tldredirect-production.out.vcl @@ -36,8 +36,9 @@ sub vcl_error { if (obj.status == 801) { set obj.status = 301; set obj.response = "Moved Permanently"; - set obj.http.Location = "https://" req.http.host req.url; + set obj.http.Location = "https://www.gov.uk" req.url; set obj.http.Fastly-Backend-Name = "force_ssl"; + # Strict-Transport-Security header is ignored for http:// requests } if (obj.status == 802) { diff --git a/spec/test-outputs/tldredirect-staging.out.vcl b/spec/test-outputs/tldredirect-staging.out.vcl index 03042098..7e7aa1bf 100644 --- a/spec/test-outputs/tldredirect-staging.out.vcl +++ b/spec/test-outputs/tldredirect-staging.out.vcl @@ -36,8 +36,9 @@ sub vcl_error { if (obj.status == 801) { set obj.status = 301; set obj.response = "Moved Permanently"; - set obj.http.Location = "https://" req.http.host req.url; + set obj.http.Location = "https://www.gov.uk" req.url; set obj.http.Fastly-Backend-Name = "force_ssl"; + # Strict-Transport-Security header is ignored for http:// requests } if (obj.status == 802) { diff --git a/spec/test-outputs/tldredirect-test.out.vcl b/spec/test-outputs/tldredirect-test.out.vcl index 03042098..7e7aa1bf 100644 --- a/spec/test-outputs/tldredirect-test.out.vcl +++ b/spec/test-outputs/tldredirect-test.out.vcl @@ -36,8 +36,9 @@ sub vcl_error { if (obj.status == 801) { set obj.status = 301; set obj.response = "Moved Permanently"; - set obj.http.Location = "https://" req.http.host req.url; + set obj.http.Location = "https://www.gov.uk" req.url; set obj.http.Fastly-Backend-Name = "force_ssl"; + # Strict-Transport-Security header is ignored for http:// requests } if (obj.status == 802) { diff --git a/vcl_templates/tldredirect.vcl.erb b/vcl_templates/tldredirect.vcl.erb index 03042098..7e7aa1bf 100644 --- a/vcl_templates/tldredirect.vcl.erb +++ b/vcl_templates/tldredirect.vcl.erb @@ -36,8 +36,9 @@ sub vcl_error { if (obj.status == 801) { set obj.status = 301; set obj.response = "Moved Permanently"; - set obj.http.Location = "https://" req.http.host req.url; + set obj.http.Location = "https://www.gov.uk" req.url; set obj.http.Fastly-Backend-Name = "force_ssl"; + # Strict-Transport-Security header is ignored for http:// requests } if (obj.status == 802) {