Earlier this year, I - along with some members of our DevOps team - noticed some interesting behavior in libmysqlclient and the MySQL CLI: no matter how hard we tried (no matter how many MYSQL_OPT_SSL_* options we set) we could not make the client enforce the use of SSL. If the server claimed not to support it, the client would happily communicate over plain old, unencrypted TCP!
This means that MySQL clients are super-vulnerable to an attack along the lines of Moxie Marlinspike's sslstrip: a Man-In-The-Middle attacker (to conform with academic norms, let's call her Mallory) can intercept the MySQL server's handshake packet, unset the flag that says "I support SSL", and then observe every query and response, or even inject her own!
Now, if you're an avid MySQL user, you might be thinking "but wait - I can just use the REQUIRE SSL option on my server..." Nope! That's the beauty of ssl-stripping attacks: Mallory can initiate a bona-fide TLS session with the server, while continuing to speak plaintext with the client . Or, to put it in somewhat more technical terms (it may be helpful to refer to the MySQL Protocol Spec), Mallory can:
- Unset the CLIENT_SSL flag in the Initial Handshake Packet
- Construct an SSL Connection Request Packet from the Handshake Response Packet (i.e. take the first 32 bytes of the Handshake Response Packet, and set the CLIENT_SSL flag)
- Perform a TLS handshake with the server
- Proxy traffic back and forth between the client and server (Since the server has seen one more packet than the client, Mallory will also have to increment and decrement packet sequence IDs for a few roundtrips until they reset).
Sadly, this sort of vulnerability is not at all uncommon; aside from HTTP (again, see sslstrip), just about all e-mail delivery across the internet has a similar - if not actually worse - affliction. However: it's really hard to totally solve these issues for ancient, widely-implemented protocols like HTTP (HSTS notwithstanding) and SMTP without, well, breaking the internet. MySQL is a different story...
Actually, the good news is that the MySQL team has already realized this was a problem, and implemented a fix. Like, over a year ago. The bad news? The fix was only applied to MySQL 5.7.3 and later; 5.7.x is not yet even a GA release! (Also, the fix was applied to version 6.1.3 of the standalone libmysqlclient distribution). The worse news? In many cases, the "fix" is not enabled by default! So, while we haven't collected any real data on the subject, we're pretty confident that the vast majority of libmysqlclient users are affected by this issue.
Now, for most MySQL users, this vulnerability probably isn't panic-worthy: as mentioned earlier, Mallory has to be in a position to perform a Man-In-The-Middle attack between the database and its client(s). It's pretty typical for a database server to be adjacent to (or even on the same box as) its client - e.g. a web application server - so MITM attacks might not be a serious concern. We also expect that many MySQL users don't bother to enable SSL at all. That said, it is clear from the libmysqlclient documentation that its developers intended to defend against this very threat:
MYSQL_OPT_SSL_VERIFY_SERVER_CERT (argument type: my_bool *)
Enable or disable verification of the server's Common Name value in its certificate against the host name used when connecting to the server. The connection is rejected if there is a mismatch. This feature can be used to prevent man-in-the-middle attacks. Verification is disabled by default.
In all but the newest versions of libmysqlclient, the bolded claim above is demonstrably false.
So, in an effort to raise awareness about this issue, we reported it to oCERT, who worked with project maintainers and vendors to coordinate disclosure of an advisory; CVE-2015-3152 has been assigned.
UPDATE: Check out Todd Farmer's response to the oCERT advisory. There's some great information there!
Stay tuned to http://backronym.fail for all the latest developments!