In the past 4 years, the adoption rate of HTTPS (between web browsers and web applications) has steadily increased as reported by the Google Transparency Report. In addition, a large number of tools like testssl.sh, O-Saft, and Qualys SSL Labs have emerged to help test and ensure proper TLS configuration across common web servers. This makes it easier for administrators to configure web application front-ends with strong cryptography, and will go a long way in protecting customer data across insecure or untrustworthy networks.

Unfortunately, the back-end of the web application framework has not kept pace. Imagine the simplest web application architecture


The Simple Web Application

with a web client, a web application server, and a back-end data store such as a relational database management system (RDBMS). All critical information that is passed across the front-end network is also passed across the back-end network to and from persistent storage. The in-transit security guarantees of these two network hops must be equal, because the sensitivity of the data traversing them is, but much less attention has been paid to the second hop. 

Previously, there was no easy way to dynamically test the TLS configuration of these popular data stores. Security Innovation has added the capability to test for common TLS misconfigurations in MySQL and PostgreSQL databases to the popular testssl.sh TLS tool. Version 2.9.5, the most recent release, can quickly confirm whether these database products are configured with the latest TLS protocol version, the strongest cipher suites, and a properly validated certificate chain, and whether they mitigate all known TLS vulnerabilities.

To run automated TLS verification on these two platforms from a Linux client, follow these steps:

1) Download the lasted version 2.9.5 of the testssl.sh tool and supporting files:
$ wget https://github.com/drwetter/testssl.sh/archive/2.9.5.zip
$ unzip 2.9.5.zip
$ cd testssl.sh-2.9.5

2) Download and uncompress the latest custom compiled openssl binary:
$ wget https://testssl.sh/openssl-1.0.2k-dev-chacha.pm.ipv6.Linux+FreeBSD.tar.gz
$ tar -xvf openssl-1.0.2k-dev-chacha.pm.ipv6.Linux+FreeBSD.tar.gz

3) Run testssl.sh against the database instance

             MySQL            
             $ ./testssl.sh --openssl ./bin/openssl.Linux.x86_64.static --starttls mysql
             <hostname>:3306

            PostgreSQL
            $ ./testssl.sh --openssl ./bin/openssl.Linux.x86_64.static --starttls
            postgres
<hostname>:5432

There are a few important differences between the TLS configuration on a
web server versus these two databases:

  • Both services implement the TLS protocol using an extension called STARTTLS.
    This allows a client to start an unencrypted connection to the database and then have it upgrade to an encrypted connection. Unfortunately, this upgrade negotiation is not protected, and thus a man-in-the-middle attacker can prevent the upgrade and force the client to use plaintext communication. The only way to mitigate this attack is to require TLS for all connections to the database, akin to disabling HTTP and only allowing HTTPS connections on a web server. Both of the database systems support this, but currently testssl.sh only checks whether TLS is enabled, not whether plaintext protocol connections are disabled. So this scenario must still be manually reviewed by the administrator.
  • The RDBM system has greatly fewer client instances and implementations, most of which are under the control of the application developer.
    There’s little need for TLS backwards compatibility to support older clients, as web servers must do, allowing the RDBMS administrator to set the strongest TLS settings possible on both client and server.

In running testssl.sh against recent versions of MySQL (5.7.18) and PostgreSQL (9.5.7), Security Innovation engineers discovered that each have deployment-blocking issues in their default TLS settings. The default configurations should NOT be used. Instead use the following TLS settings for the most secure in-transit data security.

MySQL Community Edition (built with yaSSL):
tls_version = TLSv1.1
ssl-cert    = <certificate file name>
ssl-key     = <secret key file name>
ssl-cipher  = DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA
require_secure_transport = ON 

MySQL Enterprise Edition (built with OpenSSL): 
tls_version = TLSv1.2
ssl-cert    = <certificate .pem file name>
ssl-key     = <secret key.pem file name>
require_secure_transport = ON 

PostgreSQL:
postgresql.conf:
ssl = on
ssl_ciphers    = 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256'
ssl_prefer_server_ciphers = on
ssl_ecdh_curve = 'prime256v1'
ssl_cert_file  = <full path to certificate .pem file>
ssl_key_file   = <full path to sercret key .pem file>

pg_hba.conf:
hostssl all             all             <CIDR address of client range>         md5

As illustrated, testing the TLS configuration of these popular data stores is critical to protecting the full web application. With this new tool administrators can verify true end-to-end security of their customer data in transit from the client to the hard disk and back again.