Today, oCERT published advisory 2015-003 describing a TLS vulnerability in MySQL and derivative products. The content isn’t exactly news – it is documented legacy behavior and the subject of an earlier blog post describing how MySQL Server 5.7 solves the problem. That said, the efforts of Duo Security are certainly appreciated and welcomed – it provides a meaningful context to discuss how to properly harden existing MySQL 5.5 and 5.6 deployments, as well as frame a discussion on potential changes in these versions to increase security.
The vulnerability described in the advisory relies on the legacy behavior of the client –ssl option, which simply enables – but does not require – TLS connections. When connecting to a MySQL Server which has TLS enabled, this will normally result in TLS being used for the connection. When the server does not support TLS, though, the connection will be established without TLS. For versions of MySQL prior to 5.7.3, there is no means on the client side to require TLS connections. This allows an attacker with the ability to actively manipulate network packets to silently negotiate away TLS.
Such attacks require the ability to manipulate packets between the MySQL Server and client on the network in real time. There are several options to secure connections over untrusted networks where such activity may take place, but they were unfortunately not referenced in the advisory.
Secure communication has several aspects – not only does the data need to be encrypted, but identity needs to be established. It’s insufficient to know nobody other than the recipient can read data being sent if the identity of the recipient is unknown. A client may encrypt data, but if it’s being sent to somebody impersonating a MySQL Server, the data is compromised.
When an account is configured with the REQUIRE X509 option, the client must provide an acceptable certificate matching the criteria defined in the GRANT command – and doing so requires TLS connections from the client. In such cases, an nefarious proxy cannot negotiate away TLS.
Use of client-side key material is surely uncommon, but in a deployment where MySQL communication must be secured across an untrusted network, it’s a necessary step. More details about configuration to use client-side key material can be found in the manual, and don’t forget that you can use the new mysql_ssl_rsa_setup utility from MySQL 5.7 packages to easily produce client key material (obviously, properly-signed keys are preferred).
Please note that defining accounts with the REQUIRE SSL option is not sufficient to bypass this vulnerability – a nefarious proxy could easily establish a SSL connection between the proxy and the server, while leaving the proxy’s own connection to the client in plain-text.
Use SSH Tunnels
If setting up client-side key material is too much of a burden, you can secure your communication by using a SSH tunnel instead of TLS. Tools such as MySQL Workbench make such connections even easier.
Use 5.7.3+ Clients
The easiest solution is to use clients from MySQL Server 5.7.3 or above. While MySQL 5.7 is not yet GA (it is in Release Candidate state as I write this), there’s no reason you cannot use just the client programs out of the 5.7 package which allow TLS to be required with the –ssl option – they will work just fine with 5.5 or 5.6 servers.
Possible behavioral changes in 5.5 and 5.6
The legacy behavior that prevents clients from requiring TLS connections is clearly undesirable, but Oracle takes great pains to avoid behavioral changes in maintenance releases for already-GA products. For that reason, the –ssl option was redefined to require TLS only in 5.7, where it accompanies a change that makes TLS preferred by default. The latter change has potential significant impacts to users and third-party products, and cannot be reasonably back-ported to 5.5 or 5.6. However, we are considering back-porting the change which redefines –ssl to mean “TLS is required” to these versions. Below are some details and considerations – we would love to hear your feedback.
Impacts to existing users of –ssl
It’s my belief that most users who specify –ssl as a client option actually intend for the resulting connection to use TLS, and not simply allow TLS. Furthermore, most users who specify –ssl today would likely prefer – or even expect – connections to fail when TLS cannot be negotiated successfully. Back-porting the 5.7 changes would align behavior with most user expectations (as I perceive them).
There may be users who actually understand and rely on legacy behavior, and have specified –ssl even though target servers do not support TLS. If the 5.7 behavior is back-ported, such users will find that where previous client versions established non-secure connections without notice, new connections will fail until the –ssl option is removed.
Users who want legacy behavior may obtain that by specifying other TLS-related client options, such as –ssl-cert, but without –ssl. This would require changes to user scripts which rely on legacy –ssl behavior, though.
Alternative: Implement new multi-state option
The –ssl option is a boolean configuration option, and as of MySQL 5.7, there are currently three different TLS “modes”:
- TLS disabled
- TLS preferred
- TLS required
In MySQL 5.7, TLS preferred is the default state; TLS required results from setting –ssl; TLS disabled can be triggered using –skip-ssl (among other boolean configuration variants). One option considered is to eliminate the –ssl option over time, and replace it with a multi-value option, such as –ssl-mode=[DISABLE|PREFER|REQUIRE]. This would need to co-exist with the –ssl option for a while, but at some point, the –ssl option would be deprecated and removed. This would result in requiring all scripts using –ssl to be modified, and likely causing pain for users whose scripts cannot deal with new deprecation warnings, even before functionality is fully removed.
The oCERT advisory highlights changes already made to MySQL Server 5.7 to improve security, and provides a context to discuss potential back-ports to MySQL 5.6 and 5.5. There are also meaningful steps which users of MySQL 5.5 or 5.6 can take today to eliminate exposure to this vulnerability.