Forcing Wordpress sites to use https even when not directed
code.google.com
code.google.com
For a header called "HTTPS" to be turned into $_SERVER['HTTPS'] as opposed to $_SERVER['HTTP_HTTPS'] would require quite an impressive misconfiguration of the web server which also requires additional work compared to default settings (including possibly even patching PHP itself depending on SAPI).
https://github.com/woothemes/woocommerce/issues/8479
So "breaking web applications everywhere" is an exaggeration.
It also looks like this is the implementation of the W3 "upgrade-insecure-requests" spec, so "Chrome 44 sending HTTPs header by mistake" is also not true. It's intentional.
http://www.w3.org/TR/upgrade-insecure-requests/
But it sounds like they're going to implement a different header / propose changes to the spec based on real-world feedback like this.
Has anyone actually confirmed the problem on a non-WooCommerce site? or a site without bad PHP code?
I'd just like to say that this, indeed, appears to be the case. Apache bug most likely.
Usually, yes. But CGI has some headers that don't get that prefix, things like "CONTENT_LENGTH".
It looks to me like whoever added the HTTPS variable feature to Apache implemented it as an unprefixed header rather than a proper CGI variable, for some reason, and that's the issue.
That, or it is a CGI var, but some error in Apache allows HTTP headers to set it.
But I definitely defer to your wisdom as I'm just a user who hasn't done pure CGI in 15 years. As somebody who works on PHP, you are probably infinitely more qualified
1) Implement a draft header from the W3 at this stage (which I think this is from what I can see.. there's even some fun debate about how many characters long it should be: https://github.com/w3c/webappsec/issues/216). Do they really expect webservers to handle this correctly?
2) Despite having a bug like this open in Beta, allow this to get out to Prod! Surely it's obvious this is a major breaking change?!
edit: here's the working draft document: http://www.w3.org/TR/upgrade-insecure-requests/#preference
2) During the beta, they didn't receive enough feedback to evaluate the criticality of the problem, they assumed that the fix could wait 6 weeks.
Header bloat, ~28 extra bytes per request from every Chrome user in the world.
The whole idea of the header is odd, it should be something the server could send to the client, if needed, not something the client should announce support for.
Crazy indeed.
However, this header is (or was) used by several HTTP servers/proxies (including Apache, I believe) to notify the application that the client connection is established in HTTPS. Wordpress reacts to this header by generating https:// URLs, which may not work if the server doesn't serve HTTPS with a properly configured certificate.
Surely only the most obscure, ancient legacy systems would have problems with being redirected to https?
A client may have reasons to prefer HTTP over HTTPS: perfs, plaintext for debug, etc. It's hard to assume that "HTTPS should be the default" in any circumstance.
I'm not sure the wordpress sites are to blame here (for once): SSL isn't free to deploy (yet).
If you have a site that gets enough traffic that you need a better supported or more validated certificate, then I'm sure the $40/yr for a cheapass godaddy cert is worth the money.
No, even a free certificate doesn't mean that deploying ssl is free.
In practice, with X-Forwarded-Proto, they don't, unless they can authenticate the downstream hop.
Let's say you configure your frontend server to set X-Foo and X-Bar fields. First, it should always send a header to the application indicating that it's messing with X-Foo and X-Bar, say "X-Added-By-My-Webserver: X-Foo, X-Bar". That way, the application can be sure that the frontend server is properly configured. Next, it should strip any X-Foo, X-Bar, and X-Added-By-My-Webserver, to prevent the client from being able to confuse the application with information the application expects to receive from the server.
This is still flaky because the frontend server could fail, and the user could send X-Added-By-My-Webserver, and so on, but if you must use in-band signalling, this seems like the safe route. Just blissfully adding a header is not enough to protect against evil or changing user agents.
Furthermore, it seems like a bad idea to make up your own header and not use an X- prefix.
In fact, we aren't talking about application headers. The HTTP RFC makes a distinction between application headers and hop-by-hop headers. There are mechanisms that proxies are required to implement, but they still don't.
For instance, a proxy must declare itself by appending its signature to a "Via" header - however most of them don't.
The RFC about forwarded HTTP extension is unclear about how a hop should deal with those headers, there is no one-size-fit-all situations: http://tools.ietf.org/html/rfc7239#section-8.1
I believe it is known that some old reverse-proxies used this header before a standard solution emerged (X-forwarded-proto), Wordpress probably had to deal with this surprising behavior at some point.
Also, by naming a header "HTTPS", one could expect collision with a non-standard behavior: this is very common with HTTP/1.1.
The problem is, the using "HTTPS" HTTP header (that translates to "HTTP_HTTPS" environment variable in CGI terms) is a kludge. It should've been bare "HTTPS" variable in a same manner "REQUEST_ADDR" is, but someone didn't care much (or wasn't able to do things properly in early days) but shared a recipe that became so widespread, it's a nearly de-facto standard now. Or maybe this had evolved when TLS termination proxies were much more common, but due to laziness the recipe had eventually lost mandatory sanitization of X-Forwarded-For and HTTPS headers.
Still, if webserver is unaware of HTTPS (say, it had never ever had anything with TLS) it's not really webserver's fault it's not dropping some request header.
Otherwise app code that's _checking_ the flag, to ensure that a sensitive URL is only being accessed via HTTPS can be spoofed by the client simply saying it's HTTPS when it's not. That doesn't seem right.
If that's what's going on, it seems like a bug in apache, with security consequences.
?
This issue does not render all non-HTTPS WP sites useless. I tried on a friend’s site and it served fine in Chrome version 44.0.2403.89.
After skimming the bug report it seems to mostly affect the login functionality and not the user-facing parts of WP. Still problematic but less severe than what it sounds like.
Their site must have an unused HTTPS version, then.
Yes, standards are great. But you can't break sites.
To take your extrapolation in the other direction: you're arguing that if we want to hit old stuff that we need to do it in a VM running Windows 98 and IE4.
$_SERVER is an array containing information such as headers, paths, and script locations.
You may or may not find any of the following elements in $_SERVER.
'HTTPS'
Set to a non-empty value if the script was queried through the HTTPS protocol.
https://secure.php.net/manual/en/reserved.variables.server.p...Apache's says to look into the HTTPS variable (that it adds itself before passing the call to the handler) to know if the call was made over https, but then it overwrite that variable with the browser-sent header if there is one (or more exactly, it uses the same variable name for that header and it's own HTTPS indicator; so it overwrites if both are present, and if only the header is present then it creates it when it shouldn't -- the issue in this post).
Chrome doesn't do anything wrong, but somehow the fix still has to be done inside Chrome.
Interesting how it all starts looking like one giant app, were a small change in one part leads to failures in completely unpredictable places.
Chrome is "breaking the internet" for its users, so Chrome is doing something wrong.
More technical info here: https://ma.ttias.be/chrome-44-sending-https-header-by-mistak...
I just stood up a WordPress site on Sunday running on nginx + HHVM (FastCGI), and it's not experiencing any issues.
Disagreed! This is a great week to see which sites break because of this in order to avoid them in the future. (Yes, leading a life without Flash, PHP, Node and all the other horrible technologies that came out of the web is possible!)