Mysql的UTF8与UTF8mb4
由于某个神秘项目的需要,出现了一个导入上亿条 utf8 数据到 mysql 5.7 中的需求,在实际使用的过程中,我发现 node 在向数据库中写入中文数据时会出现类似下面的报错
failed: Error: Incorrect string value: '\\xC4\\x83ri' for column 'name' at row 1
于是我猜测是字符编码的问题,于是就将编码全都改成了 utf8,但尝试过后还是存在这个报错,遂上 stackoverflow 学习了以下前人的经验,发现了一篇文章 How to support full Unicode in MySQL databases · Mathias Bynens 这里详细讲解了 mysql 中 utf8 编码的问题,并且指出 mysql 中推荐一直使用完整的 utf8mb4 编码,这里对文章做了一个翻译
修改库、表、列
- 数据库名
ALTER DATABASE 库 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
- 表名
ALTER TABLE 表 CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
- 列名
ALTER TABLE 表 CHANGE 列1 列2 VARCHAR(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
修改配置文件
[client]
default-character-set = utf8mb4
[mysql]
default-character-set = utf8mb4
[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
然后重启服务
sudo service mysql restart
检查更改结果
最终的修改结果应该如下所示,注意其中只有系统编码还是 utf8
mysql> SHOW VARIABLES WHERE Variable_name LIKE 'character_set_%' OR Variable_name LIKE 'collation%';
+--------------------------+--------------------+
| Variable_name | Value |
+--------------------------+--------------------+
| character_set_client | utf8mb4 |
| character_set_connection | utf8mb4 |
| character_set_database | utf8mb4 |
| character_set_filesystem | binary |
| character_set_results | utf8mb4 |
| character_set_server | utf8mb4 |
| character_set_system | utf8 |
| collation_connection | utf8mb4_unicode_ci |
| collation_database | utf8mb4_unicode_ci |
| collation_server | utf8mb4_unicode_ci |
+--------------------------+--------------------+
10 rows in set (0.00 sec)
思考
由于 mysql 并没有对 utf8mb4 编码进行大力推荐使用,导致现在很多的项目还在使用不完整的 utf8 编码,这里我就联想到了 mysql 中 GBK 编码存在的宽字节注入
宽字节注入:因为字符集不同 躲过 SQL 注入过滤函数
addslashes()
使addslashes
过滤的单引号、双引号、反斜杠、NULL可以利用,从而绕过SQL注入防护达成SQL注入
也是因为字符集不统一造成的逃逸,这里的 utf8 虽然我还没有看到相关的文章对其进行利用,不过这里显然是存在安全风险的,特别是对于中文站点,自我感觉容易造成二次注入,所以要注意以后使用 mysql 的时候一定要规避 utf8 编码,全部换成 utf8mb4,也不差那一字节的空间。
参考
- How to support full Unicode in MySQL databases · Mathias Bynens
- Mysql encoding error
- Mysql-字符集漏洞分析
- Mysql字符编码利用技巧
- The End -
服务器不可用,评论处于只读状态,请联系 me@vaala.cat 修复该问题