Fixed Paypal going TLS 1.2 only in June 2016

Xon

Well-known member
XenForo has a fallback path when it talks to Paypal using cURL.

The default is to attempt to connect with earlier versions of SSL/TLS, which is rejected.

The CURL branch needs to include the code:
Code:
curl_setopt($ch, CURLOPT_SSLVERSION, 6);

This can be tested when talking to the dev sandbox which has been switched over to TLS 1.2 only.

I haven't tested to see if php streams does the right thing and uses TLS1.2, but I was bitten by curl doing something stupid in another setting.
 
So much for android phones running less than 5.x? I assume this effects both the IPN and the site? The app should be fine since its both available defaulted off in the os and can be handled in app anyways.

Good stuff. Hopefully this gets Xenforo ahead of the curve, plugin devs too.
 
This is really far more evil than you might think. Given the research I'm doing, I'm incredibly surprised PayPal is going ahead with this as it's fairly difficult to support in some cases. Unfortunately, there's fairly limited amount of work that I can do to workaround this, though there is something I want to query about the suggested fix (at the end).

The core of the issue is that TLS 1.2 support isn't that pervasive when it comes to the PHP world. If PHP doesn't have support for TLS 1.2, there's nothing XF can legitimately do about that. We'd be looking for TLS 1.2 support in one of two places:
  • PHP sockets transports. I can determine this using stream_get_transports() and looking for "tlsv1.2" as far as I can tell. I have an example case where only "tls" is present and this errors when connecting.
  • cURL. Essentially, I can't determine whether cURL will support TLS 1.2.
Whether cURL supports TLS really depends on SSL library it was compiled against and the cURL version. For example, when compiled against NSS, TLS > 1.0 isn't supported until 7.34.0. It doesn't appear to be supported with WinSSL until 7.36.0, whereas DarwinSSL got it back in 7.28.0. The constant CURL_SSLVERSION_TLSv1_2 (6) itself isn't supported in cURL until 7.34.0. My understanding is that prior to that, it is equivalent to 0 (CURL_SSLVERSION_DEFAULT) which will attempt to figure out the protocol to use.

In terms of PHP itself, while I believe I can determine whether it's supported as mentioned, this is likely to require OpenSSL newer than 0.9.8. This might not be too arduous, but it's certainly not guaranteed. As an example, MAMP and XAMPP are currently compiled against 0.9.8 (https://github.com/paypal/PayPal-PHP-SDK/issues/484#issuecomment-176240130). I suspect the PHP using PHP 5.3.3 (which was the bundled RHEL/CentOS version) may well all be compiled against this. Their cURL probably will be too, so they have no workaround short of upgrading to a build that does work.

I think at best we can do the TLS test and provide a big warning if it fails. I believe that if we check for socket support and use that if available and then fallback to cURL (if available) is the extent of the approach that can be taken.

@Xon, are you sure that forcing the SSL version is needed? It should negotiate and figure it out by default. In at least one of our tests so far, it hasn't been needed. PayPal has a quick one liner in their PHP section that you can check: https://github.com/paypal/TLS-update I don't think the line should necessarily hurt, at least not in the short to medium term, but I just don't think it's necessary.
 
I think we do have an example server where forcing TLS 1.2 is needed in cURL, though it does seem like the docs imply it's not necessary. I don't know the specific reason why this one server needed it yet.

@Xon, if it's needed on your server, would you mind telling me the cURL version as listed in PHP info, only with the SSL library version it's built with?
 
@Xon, are you sure that forcing the SSL version is needed? It should negotiate and figure it out by default. In at least one of our tests so far, it hasn't been needed. PayPal has a quick one liner in their PHP section that you can check: https://github.com/paypal/TLS-update I don't think the line should necessarily hurt, at least not in the short to medium term, but I just don't think it's necessary.
I discovered this while debugging a payment gateway at work, running on CentOS 6.7, with php 5.3.3, php was build against curl 7.19.7, and openssl 1.0.1e. The paypal staging environment was being rather flaky for a couple days around then, so they might have fixed server config.

I investigated XenForo, and discovered the cURL fallback code which was effectively identical to how we where using cURL to talk to paypal. We had to break out a packet capture to identify the SSL handshake was being terminated very early in the connection cycle.
 
Last edited:
I've actually managed to reproduce the SSL version forcing thing on the XenForo.com server as well (cURL here is using NSS), so I suspect we will need to do something with that. Sockets would still be the preference, since we should be able to know whether it will work.
 
I'm incredibly surprised PayPal is going ahead with this as it's fairly difficult to support in some cases
From what I've read, it is PCI DSS v3.1 change which is forcing TLS1.0 and TLS1.1 to be considered insecure for handling payment/credit card data.

Here is a cloudflare support article about how TLS1.0 and TLS 1.1 aren't sufficient to meet PCI DSS v3.1 standards.
 
I actually noted that and pretty much simultaneously saw your post. Thanks for the CF article link. It's mentioned in the CF article, but I found an official PCI DSS blog post that indicates that they've actually pushed back the cutoff requirement date until 30 June 2018. I wonder if we'll see PayPal delay the planned changes.
 
I've adjusted how PayPal gets an HTTP client to try to get one that supports TLS 1.2. I've also added a check that runs against PayPal's TLS test on the user upgrade list page (where you configure your PP details) that will display a warning if the TLS 1.2 test fails. If it fails, it will require updated SSL libraries on your server (and then likely a PHP/web server restart). If PayPal's connection when validating IPNs fails, it will also log a server error explicitly (though this could just be from a temporary network issue).

So to be clear, we've done our best to get a transport system that supports TLS 1.2, but if you don't have one--which won't be that uncommon on older systems--you'll need to do server updates, ideally sometime before mid-June of this year.
 
Back
Top Bottom