Chrome 62 Says Not Secure When You Type: Moving Your Site to HTTPS
Chrome 62 went to the stable channel on Tuesday, and if you still run anything over plain HTTP, your visitors are about to see the words “Not secure” a lot more. The Chrome Releases post from October 17 says it rolls out to Windows, Mac and Linux over the coming days and weeks. The change was announced in April, but it still stings: a contact form or search box on an HTTP page now earns a warning the moment someone starts typing. Good week to plan the move to HTTPS.
Chrome 56 was the first step
Google laid out the plan in September 2016 in Moving towards a more secure web. Chrome had shown HTTP with a neutral indicator, which the post says doesn’t reflect the real lack of security, since someone else on the network can look at or modify a page before it reaches you. Starting with Chrome 56 in January 2017, HTTP pages with password or credit card fields got labeled “Not secure,” the first step in a long term plan to mark all HTTP as non-secure. It goes in stages because, per the post, people don’t read a missing “secure” icon as a warning, but they also go blind to warnings they see too often.
Google’s developer guide for that phase, Avoiding the Not Secure Warning in Chrome, is precise about what counts. Any form with an <input type=password> and any input detected as a credit card field has to be on a secure origin, meaning the top level page is HTTPS and so is any iframe holding the field. An HTTPS login iframe inside an HTTP page is explicitly not enough.
What Chrome 62 adds
The follow up, Next Steps Toward More Connection Security, came out April 27. It reported a 23% drop since Chrome 56 in the fraction of desktop navigations to HTTP pages with password or credit card forms. Starting in version 62, Chrome shows “Not secure” when users type data into an HTTP page, because passwords and card numbers aren’t the only things that should stay private. It also warns on every HTTP page in Incognito mode, where people likely expect more privacy even though HTTP isn’t private from anyone on the network.
The Chromium project’s page on marking HTTP as non-secure puts it more mechanically. In the Chrome 62 phase the label appears in Incognito, when the page has a password field, or when the user interacts with any input field. Both posts say the eventual goal is warning on all HTTP pages, and the 2016 post says the HTTP indicator will eventually become the red triangle Chrome uses for broken HTTPS.
Why the push
The reasoning is simple. HTTP can be read and changed by anyone on the path, and a browser that stays quiet about it sends the wrong signal. Both announcements end with the same pitch: HTTPS is easier and cheaper than ever, it enables the best performance the web offers, and it’s the way to powerful new features too sensitive for HTTP. The 2016 post noted that more than half of Chrome desktop page loads were already HTTPS. The warnings are there to push the long tail.
Step one, get a certificate
Cost used to be the excuse, and Let’s Encrypt has mostly removed it. Its Getting Started page says that if your host has built in Let’s Encrypt support, the host requests and renews certificates for you, sometimes after you turn on a setting. If you have shell access, it recommends the Certbot ACME client for most people, and its staging environment while you experiment.
Let’s Encrypt certificates last 90 days, and the project recommends renewing every 60 because automation is the point. Take that seriously: an expired certificate is annoying today and becomes a hard outage once HSTS is on.
With the certificate installed, serve the site over HTTPS alongside HTTP for a while. Google’s Web Fundamentals guide on enabling HTTPS suggests exactly that, holding off on the redirect and HSTS until later in the migration.
Step two, fix mixed content
Mixed content is an HTTPS page pulling in HTTP resources. The same guide warns that browsers often won’t load active mixed content like scripts, CSS and iframes at all, so you get a broken page, not just a warning. It recommends making intrasite URLs relative, doing it with a script rather than by hand, and remembering stylesheets, JavaScript and CSP declarations along with the HTML.
For old content you can’t easily rewrite, there’s a shortcut. The W3C Upgrade Insecure Requests spec, a Candidate Recommendation since October 2015, defines a Content Security Policy directive you send as a header:
Content-Security-Policy: upgrade-insecure-requests
A supporting browser rewrites http:// resource URLs to https:// before requesting them, so nothing insecure hits the network, and it upgrades links to your own site but not to other sites. The spec is upfront about the catches. There’s no fallback, so a host that doesn’t serve HTTPS just fails. Browsers without support still see the old URLs, so the spec asks authors to collect violation reports and prioritize fixing the URLs people actually request. Chrome Platform Status lists support since Chrome 43, and Mozilla’s release notes list it in Firefox 42. I’d use it as a safety net during cleanup, not a reason to skip cleanup.
Step three, redirect with a 301
Once pages work over HTTPS, send everyone there. RFC 6797 says an HSTS host receiving a plain HTTP request should answer with a permanent redirect, such as 301, to the HTTPS URL. In nginx, a separate server block with the return directive does it cleanly:
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
For Apache 2.4, the httpd docs point to Redirect in the port 80 virtual host rather than mod_rewrite. Redirect defaults to a temporary 302, so ask for permanent. It keeps the rest of the path, so /blog/post lands on the same page over HTTPS:
<VirtualHost *:80>
ServerName www.example.com
Redirect permanent "/" "https://www.example.com/"
</VirtualHost>
Step four, canonicals, sitemaps and cookies
Google’s guide says to point <link rel="canonical"> tags at the HTTPS URLs so search engines know which version is real. Update the sitemap too, since the sitemaps.org protocol says every URL in a sitemap must use the same protocol and host as the sitemap file. The guide also says to set the Secure flag on every cookie, because a session cookie sent over HTTP undoes the rest.
Step five, turn on HSTS slowly
HTTP Strict Transport Security tells the browser to use only HTTPS for your host for max-age seconds, even when someone types or links http://. Under RFC 6797, browsers rewrite those URLs before loading them and end the connection on any certificate error, and the RFC advises giving users no way to click through. That’s the protection, and it’s why mistakes hurt: an expired certificate makes the site unreachable for those visitors until it’s fixed.
Browsers ignore the header over plain HTTP, and the RFC says servers must not send it there, so it belongs in your HTTPS configuration. In the nginx 443 server block:
add_header Strict-Transport-Security "max-age=300" always;
The always parameter, added in nginx 1.7.5, sends the header regardless of response code. Mind the inheritance rule: a location with its own add_header lines doesn’t inherit the server level ones. On Apache with mod_headers, in the 443 virtual host:
Header always set Strict-Transport-Security "max-age=300"
Start that small. The deployment advice on hstspreload.org ramps max-age from 5 minutes to 1 week to 1 month, checking for broken pages at each stage and waiting out the full max-age before moving on. The site’s current advice then goes to two years once you’re confident, and its stages include includeSubDomains because it’s written for sites heading toward preload.
includeSubDomains and preload deserve a pause
includeSubDomains applies the policy to every subdomain, and RFC 6797 warns that any subdomain without properly configured HTTPS becomes unreachable. Its example is certificate authorities serving CRL and OCSP over plain HTTP on a subdomain. Before adding it, check every subdomain, including the ones you forgot about.
Preload goes further. The preload token isn’t in RFC 6797; hstspreload.org uses it to accept domains into the list hardcoded into Chrome, which the site says other major browsers base their own lists on. For submissions from October 11 on, it requires a valid certificate, an HTTP to HTTPS redirect on the same host, HTTPS on all subdomains, and an HSTS header on the base domain with includeSubDomains, preload, and a max-age of at least 31536000 seconds, one year. Submissions from February 29, 2016 up to then only needed 10886400 seconds, 18 weeks. The site is blunt that inclusion can’t easily be undone: removal takes months to reach users through Chrome updates, with no guarantees for other browsers. Live with the long max-age first and decide on preload later.
The takeaway
Chrome 62 moves “Not secure” from login and checkout pages to any HTTP page where someone types, plus everything in Incognito, and Google plans to warn on all HTTP eventually. Moving to HTTPS isn’t hard, but order matters. Get an automatically renewing certificate, serve both schemes while you fix mixed content, switch to a 301 and update canonicals and sitemaps, then turn on HSTS with a short max-age and work up. Save includeSubDomains and preload for last, once every corner of your domain can keep up.