Skip to main content

Posts

Tutorial: Add a QRCODE() function to TiDB

The code for this tutorial is available here . Objectives This tutorial demonstrates how easy it is to add a new function to TiDB that can be used in a SQL-statement. We want to add a function for creating QRCodes. TiDB is aiming to be compatible with MySQL . However as the functionality we’re adding doesn’t exist in MySQL this isn’t a real concern. For reference here is the architecture of a TiDB cluster: We’re only going to add the function to TiDB (in red in the above image), which means this can’t be pushed down to TiKV or TiFlash , however for this function that’s fine. The TiDB Development Guide has a page that describes some of this and more. When adding functions to TiDB you should aim for things that can be merged into upstream TiDB instead of running and maintaining your own fork. Might be good to discuss your plans in a GitHub issue before actually starting to do any work. Step 1: Adding the function to the parser For this open parser/ast/functions.go and add th...

Visualizing the MySQL Bug Tide (2018 edition)

I've updated the bug tide graph I made in 2016 with today's data. The source code and details are here .

How caching_sha2_password leaks passwords

Oracle recently announced a new authentication plugin: caching_sha2_password . This was added in 8.0.4 , the second release candidate for MySQL 8.0. The new plugin is also made the default (can be configured by changing default_authentication_plugin . Why? Phasing out SHA1 As Oracle said in the blog post to annouce this change they want to move to a more secure hashing algorithm ( SHA256 ). Which I think is a good reason to do this. Adding salt Adding a salt makes hashes for identical passwords, but different users different. Again a good reason to do this. Performance Their earlier attempt at this resulted in sha256_password . But this resulted in slower authentication. Without using persistent connections this is a serious limitation. So again a good reason. What's wrong? If you don't use SSL/TLS it gives your password away. To protect against sending the password in cleartext over an insecure connection it encrypts the password before sending it. It does this by ...

MySQL and SSL/TLS Performance

In conversations about SSL/TLS people often say that they either don't need TLS because they trust their network or they say it is too slow to be used in production. With TLS the client and server has to do additional work, so some overhead is expected. But the price of this overhead also gives you something in return: more secure communication and more authentication options (client certificates). SSL and TLS have existed for quite a long time. First they were only used for online banking and during authentication on web sites. But slowly many websites went to full-on SSL/TLS. And with the introduction of Let's encrypt many small websites are now using SSL/TLS. And many non-HTTP protocols either add encryption or move to a HTTP based protocol. So TLS performance is very important for day-to-day usage. Many people and companies have put a lot of effort into improving TLS performance. This includes browser vendors, hardware vendors and much more. But instead of just hopi...

Network attacks on MySQL, Part 6: Loose ends

Backup traffic After securing application-to-database and replication traffic, you should also do the same for backup traffic. If you use Percona XtraBackup with streaming than you should use SSH to send your backup to a secure location. The same is true for MySQL Enterprise Backup. Also both have options to encrypt the backup itself. If you send your backup to a cloud service this is something you should really do, especially if it is not sent via SSH or HTTPS. And mysqldump and mysqlbinlog both support SSL. And you could use GnuPG, OpenSSL, WinZIP or any other tool to encrypt it. Sending credentials You could try to force the client to send credentials elsewhere. This can be done if you can control the parameters to the mysql client. It reads the config from /etc/my.cnf, ~/.my.cnf and ~/.mylogin.conf but if you for example specify a login-path and a hostname.. it connects to that host, but with the password and username from the loginpath from the encrypted ~/.mylogin.cnf file. ...

Network attacks on MySQL, Part 5: Attack on SHA256 based passwords

The mysql_sha256_password doesn't use the nonce system which is used for mysql_new_password , but instead forces the use of RSA or SSL. This is how that works: The client connects The server changes authentication to sha256 password (or default?) The server sends the RSA public key. The client encrypts the password with the RSA public key and sends it to the server. The server decrypts the password with the private key and validates it. The problem is that the client trusts public key of the server. It is possible to use --server-public-key-path=file_name . But then you need to take care of secure public key distribution yourself. So if we put a proxy between the client and the server and then have the proxy sent its own public key... then we can decrypt it and reencode it with the real public key and send it to the server. Also the decrypted password is the password, not a hash. So we then know the real password. And if SSL is used it doesn't do the RSA encryption....

Network attacks on MySQL, Part 4: SSL hostnames

In my previous blogs I told you to enable SSL/TLS and configure it to check the CA. So I followed my advice and did all that. Great! So the --ssl-mode setting was used a few times as a solution. And it has a setting we didn't use yet: VERIFY_IDENTITY . In older MySQL versions you can use --ssl-verify-server-cert . Both turn on hostname verification. The attack Get any certificate which is trusted by the configured CA, this can for example be a certificate from a development machine. And use that with a man-in-the-middle proxy. Then the client: Checks if SSL is uses ( --ssl-mode=REQUIRED ) Verify if the certificate is signed by a trusted CA ( --ssl-mode=VERIFY_CA ) Both checks succeed. But the certificate might be for testhost01.example.com and the database server might be prod-websitedb-123.example.com. Browsers by default verify hostnames, MySQL does not. Turning on hostname validation So use --ssl-mode=VERIFY_IDENTITY and everything should be fine? Well that might ...