[wp-trac] [WordPress Trac] #26010: SSL via `WP_Http_Curl` breaks on HTTP version mismatch
WordPress Trac
noreply at wordpress.org
Fri Nov 15 06:24:09 UTC 2013
#26010: SSL via `WP_Http_Curl` breaks on HTTP version mismatch
--------------------------+------------------------------
Reporter: soulseekah | Owner:
Type: defect (bug) | Status: new
Priority: normal | Milestone: Awaiting Review
Component: HTTP | Version: 3.7
Severity: minor | Resolution:
Keywords: |
--------------------------+------------------------------
Comment (by dd32):
Replying to [comment:3 soulseekah]:
> And, more importantly, why is WordPress setting `CURLOPT_HTTP_VERSION`
to 1.0? Seems like a non-sane default. Why not let cURL decide, and allow
overrides via the `httpversion` argument as usual, if set?
WP_HTTP is/was a HTTP/1.0 client, it was designed to have a consistent
input/output no matter what transport was used (there used to be 5 of
them). While it now supports HTTP/1.1 mostly, it's still defaulting to 1.0
for nothing other than "all 1.1 servers must support 1.0".
A lot of the reasoning for the failures were covered in #25716, and yes,
that was the cURL change responsible.
The root cause is due to the way that TLS spec (SSLv3) works, Under SSLv2
the following was the process a server would do:
(ok, there'll be a few back and forwards missing here)
1. Client connects, asks for SSL
2. Server responds with SSL handshake ack
3. Client sends request
4. Server sends data encrypted
5. Server waits for another request, or closes the connection
Under SSLv3 (TLS), the 5th step changes:
5. Server checks to see if client is going to send extra data, if so, back
to step 2.
6. Client Initiates SSL Shutdown handshake
7. Server responds with SSL Shutdown handshake
8. Connection Terminated.
The problem is, that many servers out there do not respect the 6/7th set,
and as a result, OpenSSL clients will generally not call a Shutdown-not-
completed error as a critical error, and will continue to return the data.
In cURL 7.31.0 that was changed, and it treated any error as fatal. In
addition to that, GnuTLS (a SSLv3-only client, which cURL can be compiled
with instead of OpenSSL) doesn't like servers which violate that spec and
fails those requests too.
By changing the HTTP version you're requesting, you're triggering the
servers to do something slightly different, in the case of nginx for
example, HTTPS GET requests, and HTTPS POST requests without a POST body
complete successfully with no changes, however, if you send a POST body it
triggers a different branch of code which closes the connection early
before it finalises the SSL shutdown handshake (If you run nginx in debug
mode, you'll even say it saying so in the logs), to get around that,
WordPress.org disabled the `lingering_close` directive to cause nginx not
to close the connection prematurely.
Ultimately, we can change core slightly to avoid these issues in some
cases by changing the request method, at the risk of being less flexible
or not working with other servers, OR, we can simply black-list certain
versions and not make requests over them, which seems safer #25738
--
Ticket URL: <http://core.trac.wordpress.org/ticket/26010#comment:5>
WordPress Trac <http://core.trac.wordpress.org/>
WordPress blogging software
More information about the wp-trac
mailing list