[CONC-342] mysql_options() with MYSQL_SET_CHARSET_NAME is broken Created: 2018-06-22 Updated: 2023-12-25 Resolved: 2018-06-23 |
|
| Status: | Closed |
| Project: | MariaDB Connector/C |
| Component/s: | None |
| Affects Version/s: | 3.0.5 |
| Fix Version/s: | N/A |
| Type: | Bug | Priority: | Major |
| Reporter: | Pali | Assignee: | Georg Richter |
| Resolution: | Won't Fix | Votes: | 0 |
| Labels: | None | ||
| Attachments: |
|
| Description |
|
MariaDB C library thinks that connection character was set to utf8mb4, but in reality not. As connection charset affects functions like mysql_real_escape_string() it is a problem. It happen only when connection charset is configured via mysql_options() call with MYSQL_SET_CHARSET_NAME prior to calling mysql_real_connect(). When charset is configured via function mysql_set_character_set() after mysql_real_connect() everything is OK. In attachment is example which demonstrate this problem. MariaDB C library thinks that charset is utf8mb4 (and based on this fact is doing escaping and other operations). But in reality only 3byte utf8 charset is used (retrieved via SELECT query), which e.g. cannot transfer new 8byte emoji.
If you add mysql_set_character_set(mysql, "utf8mb4"); after mysql_real_connect() then output is correct:
Just use last MariaDB Connnector/C 3.0.5 and try to connect to MariaDB server 5.5.52 (version which is available on the CentOS 7.3). Important part is to configure server with:
(Or latin1 or whatever different from utf8mb4) It looks like that server option skip-character-set-client-handshake cause this problem and makes client defective. But client library should not be affected by any such server configuration. This problem was discovered while developing Perl DBI driver DBD::MariaDB: https://github.com/gooddata/DBD-MariaDB. As a workaround DBD::MariaDB always change charset after mysql_real_connect() was called. |
| Comments |
| Comment by Georg Richter [ 2018-06-23 ] |
|
MariaDB Connector/C doesn't support versions < MySQL 4.1. The skip-character-set-client-handshake option explicitly tells the server to behave like < MySQL 4.1 server. There is no way to detect on the client side if this option was set without sending extra packets which will slow down the connection process. |
| Comment by Pali [ 2018-06-23 ] |
|
But in this case client application which uses MariaDB Connector/C has completely broken connection encoding which can lead to data damage, or in the worst case possible to SQL injections when mysql_real_escape_string() incorrectly escapes supplied argument (I have not tried to do this yet, but mysql_real_escape_string() depends on encoding which MariaDB Connector/C thinks that is used for connection). And MariaDB Connector/C does this without informing client application. And this happen with MariaDB server 5.5.52 (not old < 4.1). |
| Comment by Pali [ 2018-06-25 ] |
|
Also the main problem is that mysql_get_character_set_info returns incorrect information about character set when mysql_options with MYSQL_SET_CHARSET_NAME was used. |
| Comment by Pali [ 2018-11-02 ] |
|
Please reopen this ticket. In current state is MYSQL_SET_CHARSET_NAME for mysql_options() really dangerous. It affects how mysql_real_escape_string is working, it can lead to wrong escaping and possible SQL injections. Also mysql_get_character_set_info() returns incorrect information which can lead to the damaging data as they would be treated in different encoding. If MYSQL_SET_CHARSET_NAME option was set, then client should ensure that this option is properly set and propagated. And if it is not possible to check if server rejected MYSQL_SET_CHARSET_NAME due to skip-character-set-client-handshake, then client library should call mysql_set_character_set() manually to ensure that character set was properly changed. Also in documentation https://mariadb.com/kb/en/library/mysql_optionsv/ for MYSQL_SET_CHARSET_NAME there is no information about fact that this option may break mysql_get_character_set_info() and mysql_real_escape_string function and possible lead to SQL injection due to incorrect escaping. |
| Comment by Pali [ 2019-06-18 ] |
|
Hi again! Have you looked at these problems with mysql_real_escape_string and incorrect documentation which I described in previous posts? |
| Comment by Pali [ 2023-08-23 ] |
|
> There is no way to detect on the client side if this option was set without sending extra packets which will slow down the connection process. Now I saw in wireshark that MariaDB server is sending some information about changed character set in some response packets. So it means that detection on the client side should be possible now. georg Could you check it? |
| Comment by Pali [ 2023-12-25 ] |
|
georg , otto any comments for this issue? MariaDB server is returning in OK packet immediately after the Warnings value, the information about changed character_set. |
| Comment by Georg Richter [ 2023-12-25 ] |
|
It is limited to the protocol implementation. Client sends character set in client response packet, and assumes that the server will also use this character set. Similiar issue with MaxScale: MXS-4898 |