Chrome 44 Sending HTTPs Header By Mistake, Breaking (Some) Web Applications

Want to help support this blog? Try out Oh Dear, the best all-in-one monitoring tool for your entire website, co-founded by me (the guy that wrote this blogpost). Start with a 10-day trial, no strings attached.

We offer uptime monitoring, SSL checks, broken links checking, performance & cronjob monitoring, branded status pages & so much more. Try us out today!

Profile image of Mattias Geniar

Mattias Geniar, July 23, 2015

Follow me on Twitter as @mattiasgeniar

Update #1: it’s less worse than it looked, see details below.

Update #2: chrome got updated, the HTTPS-header is gone, see details below.

Now this is interesting.

In the Chrome 44 release (version 44.0.2403.89) that happened just yesterday, it appears the browser got a small bug significant change.

It’s now sending the HTTPS: 1 header on every request by default. This was probably meant as a security improvement, to suggest HTTPs to the server wherever possible, but it’s breaking WordPress and other webserver installations all over the place.

chrome_https_mistake_bug

Why? Because most PHP software uses $_SERVER['HTTPS']; to detect if the site is running behind an SSL certificate or not. This includes WordPress, Drupal and any custom PHP software that checks this header.

if ($_SERVER['HTTPS'] || $_SERVER['HTTP_HTTPS']) { 
  // Assume HTTPs, redirect or enable https:// prefixes on all resources (css/js/images/...)
  ...
}

The next planned release of Chrome is scheduled on July 27th, but they’re investigating if an emergency patch can be sent out to resolve this issue.

Bugtracker: Issue 505268: Forcing WordPress sites to use https even when not directed.

This is not going to be a fun week for Chrome users.

Update #1: only HTTP_ prefixed headers are affected.

Any request header a browser sends along, gets prefixed with HTTP_ in the $_SERVER global variable. The User-Agent gets transformed into HTTP_USER_AGENT, the Accept-header gets turned into HTTP_ACCEPT, … and so on.

Here’s what those HTTP headers look like according to PHP.

print_r($_SERVER);

Array
(
    ...
    [HTTPS] => on
    [HTTP_HOST] => ma.ttias.be
    [HTTP_ACCEPT] => text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
    [HTTP_ACCEPT_ENCODING] => gzip, deflate, sdch
    [HTTP_ACCEPT_LANGUAGE] => nl-NL,nl;q=0.8,en-US;q=0.6,en;q=0.4,fr;q=0.2,it;q=0.2
    [HTTP_COOKIE] => some=value
    [HTTP_HTTPS] => 1
    [HTTP_USER_AGENT] => Mozilla/5.0
)

The first HTTPS value in the $_SERVER variable is the one set by the webserver, to indicate HTTPs or not. The second one, HTTP_HTTPS, is the HTTPS-header sent by the Chrome browser that gets transformed into an variable for PHP.

Some PHP code, like the WooCommerce WordPress plugin didn’t only check $_SERVER['HTTPS'], but also looked at $_SERVER['HTTP_HTTPS'] to detect HTTPS on the site. This is wrong PHP code and has nothing to do with “bad PHP by design".

The HTTP_ prefix handling done by WooCommerce is probably done as a result of a Apache bug/feature that once existed, where after 301/302 HTTP rewrites some environment variables would always get prefixed with another HTTP_ keyword.

There are also reverse proxy configs (Nginx, Varnish, …) out there that also pass environment variables along that get interpreted by Apache as headers and thus receive the HTTP_ prefix.

Either way, most plugins have had an update by now, just go to your WordPress/Drupal/… site and update all plugins. Chances are, the problems will be gone, even if Chrome takes a couple more days to get the patch out.

Fixing WooCommerce specifically

Most problems are reported by WooCommerce, the WordPress plugin. Since chances are, you can’t log into your WordPress any more, you’ll need another fix. Many thanks to Rahul Lohakare in the comments for this fix.

Modify the following file, either download it via FTP and upload it again or modify it directly on the server: wp-content\plugins\woocommerce\woocommerce.php

Comment out these lines:

if ( ! isset( $_SERVER['HTTPS'] ) && ! empty( $_SERVER['HTTP_HTTPS'] ) ) {
    $_SERVER['HTTPS'] = $_SERVER['HTTP_HTTPS'];
}

Once those have been commented (just prefix every line with #), WooCommerce/WordPress won’t redirect you anymore.

If that still doesn’t work, use Firefox or another browser to log into your site and update the plugin via the official WordPress update method. Since the problem is Chrome-only, you can bypass the redirect by using any other browser, temporarily.

Update #2: Chrome got updated, replaced ‘HTTPS’ with ‘upgrade-insecure-requests’

Chrome pushed out an update, everyone should get it in a few hours. I’m now on version 44.0.2403.107, anything higher will not have this problem anymore.

chrome_update

After the update, the HTTPS header has been removed by the upgrade-insecure-request header.

chrome_header_upgrade_insecure_requests

Good news for everyone!



Want to subscribe to the cron.weekly newsletter?

I write a weekly-ish newsletter on Linux, open source & webdevelopment called cron.weekly.

It features the latest news, guides & tutorials and new open source projects. You can sign up via email below.

No spam. Just some good, practical Linux & open source content.