Wordpress/WooCommerce HTTPS/SSL - Broken URLs

UPDATE: So it looks like this change is as a result of Chrome 44 release (version 44.0.2403.89). It's now sending HTTPS: 1 by default in all request headers. Presumably to try to redirect users to a HTTPS version of the page, if it's available. This shouldn't force a HTTPS URL by itself, though, it merely sets the $_SERVER['HTTP_HTTPS'] variable, presumably so the server can see that the client is requesting SSL if it's available. WooCommerce reads this request as being a demand for SSL. The key here is that the client shouldn't be able to tell the server how to act, which is what has been allowed to happen in this instance.

(Source: Mattias Geniar)

I've just come across a pretty horrendous issue with the Wordpress plugin WooCommerce which appears to affect versions of the plugin from 2.3 to 2.3.13 and can bring down your whole site..

Yesterday, for apparently no reason, a development version of a site I'm building completely stopped working in Chrome (but I didn't actually check any other browsers). On investigation, SSL was being forced on my URLs, so whilst I was browsing to http://website.dev, all the assets and links would come up as https://website.dev. The result being that no assets would work and any attempt to get into CMS section would redirect to a dead URL. The site was completely broken.

After some playing around, I found I could hack it to work again with the following code, placed in wp-config.php:

$_SERVER['HTTPS'] = '';

It seemed as though the $_SERVER['HTTPS'] variable was being set to '1', causing Wordpress to force the protocol for the site URL to be https. At first, given it was a server variable, I'd assumed there was something I'd managed to break on the server itself. Given that I'd changed nothing in my own code or updated Wordpress or any of the plugins it uses. My setup is a Ubuntu Linux server running Apache.

Delving Deeper

But unsatsfied that I'd failed to locate the problem exactly, I dug further. I managed to find a fairly innocuous-looking function in woocommerce.php:

/**
* Fix `$_SERVER` variables for various setups.
*
* Note: Removed IIS handling due to wp_fix_server_vars()
*
* @since 2.3
*/
private function fix_server_vars() {
// NGINX Proxy
if ( ! isset( $_SERVER['REMOTE_ADDR'] ) && isset( $_SERVER['HTTP_REMOTE_ADDR'] ) ) {
$_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_REMOTE_ADDR'];
}

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

The key code here being the following:

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

I actually couldn't find any documentation on what the HTTP_HTTPS server variable does, but in my case here, $_SERVER['HTTP_HTTPS'] was set to be '1', which the WooCommerce plugin would indiscriminately assign to $_SERVER['HTTPS'] and cause Wordpress, looking for a non-empty value, to force SSL URLs.

I can only assume that newer version of Chrome are effectively asking the server if SSL is enabled in case it can browse to a more secure site. And WooCommerce, without really understanding what the $_SERVER['HTTPS'] variable actually does, have just assumed it's an alias of $_SERVER['HTTPS']. These sort of assumptions are dangerous, especially for a plugin that is used by such a huge audience.

My Advice

If you're using WooCommerce on your site, regardless of whether you've come across the issue or not, check the version you're using on the plugins page of the CMS. If it's greater than version 2.3.0, but less than 2.3.13, upgrade to the latest version immediately. This is a problem that will start affecting your Chrome users soon, if not already.

If you're a bit nervous about upgrading WooCommerce and the effects it could have on the rest of your site, add the following code to your wp-config.php file:

$_SERVER['HTTPS'] = '';

Do this with care, though, as if you do activate SSL on your server in future, this will affect that.

If you don't understand any of that and you're experiencing this issue, consult your web developer.

The Deeper Problem

When you use off-the-shelf software for your web site or anything else, you're trusting the person or organisaton that you're getting that software from to not break it. You should always be wary about what you use, especially when your business relies on it operating without issue.

This bug is a pretty large one and the WooThemes chaps should really look into how such a bug was introduced, if they haven't already. But their cursory mention of the issue in the 2.3.13 release notes suggest they don't realise the extent to which the problem could exist.

That's not to say Wordpress is free of blame in this, forcing a URL when the the user has set the options to another URL is pretty bad form too. Wordpress is a useful blogging platform, but when you add more than a handful of plugins to it, you really need to look into who it is you're putting that trust into and if there are more reliable solutions out there.

Posted on Jul 23, 2015

Discuss This

blog comments powered by Disqus