[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