Bugzilla – Bug 1029396
VUL-0: CVE-2017-3305: mysql: MySQL client send authentication request unencrypted even if SSL is REQUIRED (RIDDDLE.LINK)
Last modified: 2019-08-16 15:25:59 UTC
Hi! I discovered SSL related security problem in MySQL 5.5 and 5.6
client libraries. Public disclosure will be at 17th March.
I'm resending details about vulnerability which I sent to Debian
security team. So you would have some time to prepare if you need it
before public disclosure.
I have successfully implemented MITM script to verify that attack is
---------- Forwarded Message ----------
I'm observing strange behaviour in MySQL client. When I specify option
that SSL/TLS encryption layer is required and target MySQL server does
not support TLS then MySQL client fallbacks to unencrypted plain text
protocol and starts authentication session via it.
MySQL client *after* successful authentication checks if SSL/TLS layer
is required and if server have not support it after then it close
connection with fatal error.
This problem is present in last 5.5 (5.5.54) and also 5.6 (5.6.35)
versions. But not in last 5.7 (which seems to be fixed).
You can easily verify it by starting non-SSL MySQL server on localhost,
start wireshark and run command:
$ mysql --ssl-mode=REQUIRED -u root -ppassword -h 127.0.0.1
Then you can that authentication request is really unencrypted and sent
data are in format described at:
Active MITM attacker can downgrade SSL/TLS to plain text, forward nonce
from server back to client. MITM attacker receive from client login data
(for server nonce), send it to server and should be authenticated.
Client just detect that connection is not SSL/TLS and throws error.
Attacker in that time is already connected to MySQL server.
Note that this problem is present in libmysqlclient.so (in 5.5 and 5.6)
versions, so any application which uses it is probably vulnerable to
this attack (not only "mysql").
And if you look at documentation for MySQL 5.5 and MySQL 5.6 you can see
that *suggested* option how to enforce SSL/TLS is by first calling
mysql_real_connect() and then verify that SSL/TLS was really established
by mysql_get_ssl_cipher(). Problem is that mysql_real_connect() takes
arguments "user" and "passwd" and check for SSL/TLS is *after* that.
So probably other applications which follows MySQL documentation are
vulnerable to this attack too.
DISCLAIMER: THE FOLLOWING SECTION IS UNIMPORTANT FOR THE MAJORITY OF
PEOPLE AS IT IS NOT USEFUL FOR THE MEDIA OR ANY OTHER NEWS RELATED
WEBSITES DUE TO BORING TECHNICAL INFORMATION AND DETAILS. IT IS PROVIDED
"AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT. BY READING THE FOLLOWING SECTION YOU AGREE TO
NOT USE IT IN THE MICROWAVE. THE ENTIRE RISK AS TO THE QUALITY OF THE
FOLLOWING SECTION IS WITH YOU. YOU ASSUME THE COST OF ALL NECESSARY
SERVICING, REPAIR OR CORRECTION. ANTE USUM AGITETUR!
What is the real problem?
MySQL client library doesn't verify if security of the connection matches
the parameters specified by the user before starting negotiation of the
authentication with MySQL server. After the BACKRONYM vulnerability had
been discovered, it was fixed by Oracle in MySQL 5.7. Security update for
the stable MySQL 5.5.49 and 5.6.30 versions consisted of adding a
verification of security parameters after the authentication process was
finished. Since, it is done after the authentication man riddle in the
middle attack together with SSL-downgrade attack can be used by the
attacker to steal login data for immediate authentication and login to the
MySQL server. Ridiculous part is that MySQL client doesn't report any SSL
related error when MySQL server declines to authenticate a user and
instead reports unencrypted error message send by the server. Furthermore,
the error message is controlled by the attacker, when the riddle in the
middle attack is active.
How can the attack look like?
The attacker needs to sit with riddle in the middle of the MySQL client
and MySQL server and needs to have the ability to modify MySQL protocol
communication. Due to (not fully) secure password authentication scheme
which MySQL protocol uses, attacker can catch the server nonce from
properly secured SSL connection with MySQL server and then forward it to
the client via non-secure plain text connection. In this phase, the client
doesn't do any verification of security parameters and it also doesn't
verify if the other side that sent the the nonce really knows the password
(or have ability to verify if supplied data are correct). Thus, the client
doesn't report any problem that SSL connection isn't used and it generates
authentication response. The response is sent back to other side (to the
attacker) without any complains via insecure plain text mode. The attacker
then finds in the riddle authentication response, sends it to the real
MySQL server and voila attacker has access to MySQL server database.
Afterwards, attacker sends some error message to the client and the client
propagates it to the user. The error message can contain arbitrary string
and the client doesn't show any problems related to disabled SSL mode even
when SSL mode was explicitly set to required. The user's password isn't
disclosed as a result of the attack. The attacker can authenticate to
MySQL server without the password only once as the server nonce is always
(or should be) different. If authentication scheme were more robust (e.g.
SCRAM), then this attack wouldn't be possible. It remains to be seen
whether Oracle will be willing to switch authentication scheme to
something more robust after this vulnerability was discovered and
Which versions of the libraries are affected?
All versions of MySQL 5.5 and 5.6 client libraries (at the time of writing
of this article). Note that MariaDB client libraries aren't affected by
this vulnerability as MariaDB developers fixed BACKRONYM properly and
verification of the security parameters is done before sending user
credentials. Furthermore, all the programs which use MySQL or MariaDB
client library incorrectly are also affected.
How do I verify if a program which uses MySQL/MariaDB is affected?
Oracle in MySQL 5.5 documentation demonstrates how to enforce SSL
encryption via function mysql_connect_ssl_check(). The code example in the
documentation is incorrect as it introduces a vulnerability to your
program! In the example, the check whether SSL was established is done
after starting the authentication process. If your MySQL program uses the
recommendation or directly the code example provided by Oracle, then your
program is affected by Riddle vulnerability independently of MySQL client
library. Therefore, fixing MySQL client library isn't enough and MySQL
program must be fixed too.
How do I check if my system is affected by this defect?
You are affected if you are using MySQL client in any version 5.5 or 5.6
or you are using affected program as described above and you depend on SSL
encryption over untrusted network where attacker can apply riddle in the
How can I mitigate this problem?
You have couple of options. The best way would be to stop using the
affected libraries, either by upgrading your MySQL client to version 5.7
or by switching from MySQL to MariaDB client. You can also apply MariaDB
patch for the BACKRONYM vulnerability to your MySQL client. Note that
MySQL client is backward compatible and version 5.7 can connect to MySQL
server 5.6 or 5.5 without any problems. So, you just need to upgrade the
client without touching the server part. Another option is to stop
relaying on SSL enforced encryption by MySQL and create your own correctly
encrypted secure tunnel. You can use e.g. socat program which can create a
bidirectional SSL tunnel or use any other secure tunnel based on SSH, VPN
or IPSec. The last option is to apply ostrich effect and wait until Oracle
fixes MySQL client libraries and starts distributing them to you. In that
case, you should expect that you could be victim of a attack.
How do I use SSL encryption properly?
SSL (resp. TLS, as SSL v2/v3 is already broken but name SSL is commonly
used for TLS protocol) implementation or protocol itself isn't affected by
this vulnerability. The whole problem is how MySQL client uses SSL
encryption. Men in the middle attack is very common for SSL and to prevent
it, client must verify if SSL tunnel was correctly established with
correct server and not with some attacker's server. It means that client
must verify SSL certificate announced by the server and also that the
certificate is really owned by the server. If the connection to MySQL
server is SSL encrypted but MySQL client doesn't verify certificate
(correctly!), then man in the middle attack is still possible and
downgrade attack is needed. The Riddle vulnerability shows that MySQL
client does whole verification at wrong a time -- after the authentication
was finished. Not before. So, enforcing SSL mode isn't enough, you also
need to tell MySQL client how it must verify server's SSL certificate.
Either that it is signed by really trusted certificate authority or that
it matches server's certificate directly.
Are there some implementations of riddle in the middle already?
Yes, there is my proof of concept riddle.pl script written in Perl. It
starts riddle on localhost:3307 and expects that MySQL server is running
on localhost:3306. If you connect with affected client to localhost:3307,
then riddle will catch and steal authentication information, connects to
real MySQL server on localhost:3306 and executes SQL for returning number
of all tables.
Example which expects that MySQL server is already running on localhost:
Start riddle in the middle server:
$ perl riddle.pl
Connect with your MySQL client to riddle, replace user and password:
$ mysql --ssl-mode=REQUIRED -h 127.0.0.1 -P 3307 -u user -ppassword
If you provided correct user and password, then riddle connects to the
server, executes SQL and writes output:
SELECT COUNT(*) FROM information_schema.TABLES --> 121
MySQL client just receives a nice error message sent by riddle:
ERROR 1045 (28000): Access denied: MITM attack
* 2017-02-01 - me - Discovered the vulnerability
* 2017-02-04 - me - Contacted Debian Security team because defect was
present in Debian's libmysqlclient.so library
* 2017-02-06 - me - Provided POC perl script
* 2017-02-06 - Debian & Oracle - Oracle person CCed by Debian Security
team passed the information on upstream
* 2017-02-10 - me - Requested information about the state and progress
of the reported vulnerability
* 2017-02-16 - Debian - Asked about the state again, since there was no
answer from Oracle
* 2017-02-23 - me - Issued another request about the current state and
announced date of public disclosure to 2017-02-28 due to Oracle's
* 2017-02-23 - Debian - Suggested to disclose the vulnerability as
upstream has failed to respond
* 2017-02-24 - Debian - Contacted Oracle team again
* 2017-02-25 - Oracle - Answered that they were not aware of this issue,
even though it was already passed on to them on 2017-02-06 and I
inquired 4 times about the progress
* 2017-02-27 - Oracle - Answered that they will provide response quickly
* 2017-02-28 - me - Requested the current state again as Oracle hasn't
* 2017-02-28 - Oracle - Answered that will have response shortly
* 2017-02-28 - me - Reminded them that it was the day of public
disclosure and offered them postponing the disclosure for a few days
* 2017-02-28 - Oracle - Accepted an offer to postpone the disclosure
date to the end of week
* 2017-03-01 - me - Requested the state of the reported vulnerability
again because Oracle have not provided any information of progress yet
* 2017-03-02 - Oracle - Sent information (for the first time) that they
were actively working on this issue and asked me to keep it
confidential until the end of April
* 2017-03-02 - me - Rejected postponing disclosure date for another two
months because one month should have been enough to fix the issue and
users should have been informed about this vulnerability ASAP
* 2017-03-02 - Oracle - Informed me that it is hard to fix the reported
issue and requested everybody involved to keep this issue confidential
* 2017-03-03 - me - Repeated rejection of postponing the disclosure date
for another two months and offered them postponing the disclosure date
for one week
* 2017-03-03 - Oracle - Hasn't stated if they wanted to postpone the
disclosure, but offered inclusion of my name into a credit section if
I kept the issue confidential
* 2017-03-11 - me - Announced to Oracle, Debian Security team, Red Hat
Security team and SUSE Security team that final public disclosure is
2017-03-17 (no more postponing)
* 2017-03-17 - me - Announced the vulnerability to the oss-sec mailing
As you can see, communication with Oracle is very hard. For ordinary
people without a big company standing behind them, it probably doesn't
make any sense filing reports of security vulnerabilities. After one
month, Oracle have done absolutely nothing. They even wanted to postpone
the disclosure date for another two months as they are probably
incompetent to handle the security issues in their products. The only
thing which Oracle offered as a reward if I do not disclose this issue was
an inclusion of my name to some Oracle credit section. It is probably the
last thing which would a developer or a security expert want to see.
Conclusion: Reporting bugs to Oracle is useless (even those which are
security related) if you are not a Oracle customer. They can perfectly
ignore any reports and they would be very happy if nobody knew about it so
they don't have to fix the bugs. It looks like immediate public disclosure
is the best responsible solution for the users as it is the only way how
to protect them and let them know immediately what should be done if they
Email address: middle at riddle dot link
* Perl script riddle.pl - http://riddle.link/riddle.pl
* CVE-2017-3305 -
* BACKRONYM - http://backronym.fail/
* MySQL 5.5.49 release notes -
* MySQL 5.6.30 release notes -
* MySQL Secure Password Authentication -
* MySQL mysql_connect_ssl_check() function -
* SCRAM -
Few important highlights:
(In reply to Marcus Meissner from comment #3)
> All versions of MySQL 5.5 and 5.6 client libraries (at the time of writing
> of this article). Note that MariaDB client libraries aren't affected by
> this vulnerability...
MariaDB is not affected. Only MySQL 5.5 and 5.6 is.
> Furthermore, all the programs which use MySQL or MariaDB
> client library incorrectly are also affected.
An important word here is _incorrectly_. Libmysqlclient is not affected per se as changes that introduced this issue were made only for mysql clients shipped with MySQL. The problem is rather in the documentation that guided users to implement the same approach in their applications:
> Oracle in MySQL 5.5 documentation demonstrates how to enforce SSL
> encryption via function mysql_connect_ssl_check(). The code example in the
> documentation is incorrect as it introduces a vulnerability to your
According to the Oracle mysql-ssl-set() documentation (see a difference between the old  and the new  version of the section "Enforcing an Encrypted Connection"), they changed their mind about a backporting MYSQL_OPT_SSL_MODE option that "would break binary compatibility with previous library versions" and backported it for MySQL 5.5.55  and MySQL 5.6.36 .
In MySQL 5.5.55, the MYSQL_OPT_SSL_MODE option for mysql_options() was backported from MySQL 5.7 to MySQL 5.5. A call to mysql_options() to set MYSQL_OPT_SSL_MODE option to value of SSL_MODE_REQUIRED suffices to cause mysql_real_connect() to fail if the connection is not encrypted. mysql_get_ssl_cipher() can still be called after connecting, although it is not necessary to do so.
They also added an additional step between mysql_ssl_set() call and mysql_real_connect() call. It's an mysql_options() call with passing the MYSQL_OPT_SSL_MODE option.
In the light of this, it seems that this issue is fixed in these versions. However, it's not released yet. The next Oracle Critical Patch Update is planned for 18 April 2017 .
Unfortunately, we can't cherrypick this bugfix now as for some reason the last change in mysql-server GitHub repository  was done in November (they probably use private repo?).
Vulnerability name: The Riddle
Red Hat: https://bugzilla.redhat.com/show_bug.cgi?id=1431690
- this CVE-2017-3305 was fixed within Oracle CPU Advisory - April 2017  in:
* MySQL 5.5.55
* MySQL 5.6.36
* (MySQL 5.7 is not affected)
This is an autogenerated message for OBS integration:
This bug (1029396) was mentioned in
https://build.opensuse.org/request/show/490980 42.1+42.2 / mysql-community-server
- not affected
| Codestream | Request |
| SLE11SP3 | 131626 |
| openSUSE:Factory | 490949 |
| openSUSE:Leap:42.1 | 490980 |
| openSUSE:Leap:42.2 | 490980 |
We are done here. I'm reassigning it back to the security team.
SUSE-SU-2017:1137-1: An update that fixes 13 vulnerabilities is now available.
Category: security (important)
Bug References: 1020976,1022428,1029014,1029396,1034850
CVE References: CVE-2016-5483,CVE-2017-3302,CVE-2017-3305,CVE-2017-3308,CVE-2017-3309,CVE-2017-3329,CVE-2017-3453,CVE-2017-3456,CVE-2017-3461,CVE-2017-3462,CVE-2017-3463,CVE-2017-3464,CVE-2017-3600
SUSE Linux Enterprise Software Development Kit 11-SP4 (src): mysql-5.5.55-0.38.1
SUSE Linux Enterprise Server 11-SP4 (src): mysql-5.5.55-0.38.1
SUSE Linux Enterprise Debuginfo 11-SP4 (src): mysql-5.5.55-0.38.1
openSUSE-SU-2017:1209-1: An update that fixes 16 vulnerabilities is now available.
Category: security (important)
Bug References: 1020976,1022428,1029014,1029396,1034850,889126
CVE References: CVE-2016-5483,CVE-2017-3302,CVE-2017-3305,CVE-2017-3308,CVE-2017-3309,CVE-2017-3329,CVE-2017-3450,CVE-2017-3452,CVE-2017-3453,CVE-2017-3456,CVE-2017-3461,CVE-2017-3462,CVE-2017-3463,CVE-2017-3464,CVE-2017-3599,CVE-2017-3600
openSUSE Leap 42.2 (src): mysql-community-server-5.6.36-24.3.3
openSUSE Leap 42.1 (src): mysql-community-server-5.6.36-25.3
all fixed and released