• Content

TLS v1.0 and 1.1 Deprecation

At Recurly, we take the protection of our customers’ data very seriously. To ensure the highest security standards and promote the safety of your data, we are making security improvements and retiring older encryption protocols. To maintain alignment with these best practices and updated compliance requirements from the PCI Security Standards Council (PCI SSC), Recurly will discontinue support for TLS version 1.0 and 1.1 to our application and API effective June 30, 2018.

According to our audit of current merchant connections, you are still using version 1.0 or 1.1, and action must be taken on your part to upgrade. Failure to upgrade by June 30, 2018 will result in these connections failing to connect to our servers.

What is TLS?

SSL/TLS encrypts a channel between two endpoints to provide privacy and reliability of data transmitted over the communications channel. You will often hear it simply referred to as “SSL”. It is used by your browsers to securely connect to the Recurly dashboard and also used by your server to send information to our API.

Why you must upgrade to TLS 1.2 or above

While the PCI SSC postponed the migration completion date to June 30, 2018 for transitioning from TLS 1.0 and 1.1, Recurly is still recommending to our customers that they update to version 1.2 or above as soon as possible as it is more secure.

  • Maintain integrity and authenticity of data.
  • The vulnerabilities within SSL and TLS 1.0 and 1.1 are serious and left unaddressed put organizations at risk of being breached. An attacker could perform a man-in-the-middle attack and passively observe the contents of the messages or spoof their own messages. The existence of the POODLE and Heartbleed exploits, among others, prove that anyone using SSL and early TLS risks being breached.
  • New installations are not part of the revised compliance date and still need to be TLS 1.2 or above.

What are the risks?

Failure to upgrade connections would potentially risk the integrity and the authenticity of the data being sent between the merchant and Recurly. An attacker could perform a man-in-the-middle attack and passively observe the contents of the messages or spoof their own messages. Since Recurly is shutting down support, failure to upgrade will result in your connections being terminated.

Where can I learn more?

If you are interested in learning more, we suggest reading this migration document from the PCI Security Standards Council.

How can I fix this problem and verify the solution?

When you open a secure connection, a protocol version must first be agreed upon by both the server and the client. Unless configured to do so otherwise, the server and the client will pick the best options that they both support according to the preference of the server. It’s best to let this negotiation happen automatically so you can be sure that you are always using the best protocol specified by our server.

If you are one of the merchants affected, it is because your client is refusing to negotiate use of a protocol versions above 1.1. The reasons this may be happening will fall into one of 3 categories.

  1. You are using an old version of a Recurly library that is forcing a TLSv1.0 or or 1.1 connection (see below)
  2. You have added configuration to force 1.0 or 1.1 for one of our libraries, you have patched our library to force 1.0 or or 1.1, or your own custom client is incorrectly configured.
  3. Everything is properly configured at the application level, but your runtime environment does not support above versions 1.1

Recurly Client Library Patches

Python

If you don’t have Python >= 2.7.9 and OpenSSL >= 1.0.1 you will need to upgrade your Python environment. The change to the ssl module was only back ported to 2.7.9.

Even if Python and OpenSSL are up to date, you may be connecting with TLS 1.0 or or 1.1 due to a bug in some versions of our library. You will need to upgrade the Recurly client if both of these apply to you:

  1. You are using version 2.1.3 (released July 16th, 2012) to version 2.2.15 (released August 31, 2015)
  2. You are using the CA_CERTS_FILE option (example):
recurly.CA_CERTS_FILE = '/etc/pki/tls/certs/ca-bundle.crt'

If these apply to you, we recommend you upgrade to 2.2.22 or above. Check the releases page to see which versions are available. If this is not possible, you can apply the patch yourself or reach out to us for help. You may also be able to mitigate this problem by removing the explicit setting of CA_CERTS_FILE and letting the system find your root cert path.

Ruby

The Ruby client should not require a patch but configuration allows the programmer to supply the SSL/TLS protocol via the net_http configuration object (example):

Recurly::API.net_http = {
  ssl_version: :TLSv1,
  #...
}

If you have set this option, you will want to remove the ssl_version configuration so that the client can negotiate the best version with the server. If you find you must set this option to get it to work, you should use the constant for TLS version 1.2: TLSv1_2

PHP

The PHP client does not allow setting specific SSL/TLS protocol versions nor does it allow setting specific curl_opts. If you are experiencing this problem with PHP, we suggest that you verify that PHP and libcurl versions are up to date and support TLS 1.2. Also, please ensure you have not configured your code to force TLS 1.0 or 1.1. The libcurl constant looks like this CURL_SSLVERSION_TLSv1. If this is set, you will want to remove it.

.NET

If you are using our .NET library and your version is below 1.3.0, you will need to take action. Previous versions of the library targeted .NET 3.5 which did not contain support for TLS 1.2. This may have larger implications on your application if you are using an older version of .NET. Our recommendation is that you upgrade to the latest version of recurly-client-net 1.3.

If you are finding that upgrading to the latest version of the .NET library is not working for you, the current workaround is to set the security protocol preferences yourself on initialization of your program:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

If you are using a custom branch or your own library, you will want to ensure that you are preferencing TLS12 and TLS11 as stated above.

Java

If you are using Java 1.8, TLS1.2 is enabled by default and the TLS negotiation should just work and there should be no action required. If there are still TLS1.0 or 1.1 connections occurring, there may be something in your code explicitly downgrading it.

If you are using Java 1.7, TLS1.2 is disabled by default. You must explicitly enable it or specify the protocol when creating your SSLContext. The simplest and safest way to mitigate the issue is to make sure you are passing in the protocol version you want when creating your SSLContext:

 SSLContext context = SSLContext.getInstance("TLSv1.2");

If you are using Java 1.6 or below you will need to upgrade unless you are using a specific version of the JVM that has backported support for TLS1.2.

For more information or other ways to fix this issue, please read this article.

Other

If you are using some other language or a custom library, you will need to find the portion of your code that creates the secure socket to Recurly and look for a forced TLS version. If you find it, you should remove the option or ensure that it is the latest (TLS 1.2).

Debugging machine or runtime issues

If you believe that your runtime or your machine is preventing the negotiation from going above 1.0, we have written some scripts to help you identify this. The scripts are in Ruby, Python, and PHP so if you are using something else you will need to write an equivalent:

https://gist.github.com/bhelx/b0d5a03478e500644bbc

The scripts call the URL https://www.howsmyssl.com/a/check which returns some JSON information about the connection. It then prints out the TLS version that was used. These scripts are all set to allow the negotiation process to choose the best options (TLS1.2), if you are not seeing 1.2 then some language or machine dependency does not support a modern enough version.