MySQL中用户密码存在特殊字符的使用场景

news/2024/11/17 15:44:12/

开源社区推送的这篇文章《故障分析 | 密码使用特殊字符》,介绍了密码中包含特殊字符的情况,算是一个常见的场景,可以将这个问题增加到自己的案例知识库中。

背景

最近在使用脚本新建了一批应用用户,发现一个奇怪的问题,有部分用户存在以下问题:应用使用该密码能正常访问,但使用mysql客户端登录手动输入密码无法登录。

经过与正常用户对比发现存在登录异常的用户使用了特殊字符"$"。

问题复现

在测试环境使用脚本生成一批用户,

#新建用户脚本简化后如下
#!/bin/bash
pw="abc$2UY"
mysql --login-path=root -e"create user app@'%' identified by '$pw'"
mysql --login-path=root -e"grant insert,update,delete,select on *.* to app@'%'"#测试使用mysql客户端登录
[root@node3 ~]# mysql -h127.0.0.1 -uapp -p  #手动输入密码无法登录
Enter password:
ERROR 1045 (28000): Access denied for user 'app'@'127.0.0.1' (using password: YES)[root@node3 ~]# mysql -h127.0.0.1 -uapp -p'abc$2UY' #使用单引号无法登录
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 1045 (28000): Access denied for user 'app'@'127.0.0.1' (using password: YES)[root@node3 ~]# mysql -h127.0.0.1 -uapp -pabc$2UY #不加单引号或使用双引号都可以登录
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 15389
Server version: 8.0.18 MySQL Community Server - GPLCopyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.mysql>

问题分析

根据上面的测试,发现部分能登录部分不能登录。那为什么部分可以,部分不可以?

首先可以确认一下存入数据库的密码是否正确。

我们可以手动新建一个用户密码与app用户密码保持一致。然后比较mysql.user表中authentication_string字段是否一致。

mysql> create user test@'%' identified by 'abc$2UY';
Query OK, 0 rows affected (0.05 sec)mysql> select user,host,authentication_string from mysql.user where user in ('app','test');
+------+------+-------------------------------------------+
| user | host | authentication_string                     |
+------+------+-------------------------------------------+
| app  | %    | *06E0B7BA0149152EE2A387A144A2DF9ACC492297 |
| test | %    | *7258A15F121DD9F6F7C40C08D34A3DB5ED8C8CB5 |
+------+------+-------------------------------------------+

通过对比authentication_string字段发现两个密码不一致,说明脚本生成的用户密码并不是原来的密码了。为什么会这样呢?

我们知道在shell中使用单引号与双引号定义的字符串是有些区别的,

[root@node3 ~]# echo "abc$2UY"
abcUY
[root@node3 ~]# echo 'abc$2UY'
abc$2UY
[root@node3 ~]# echo abc$2UY
abcUY

单引号定义字符串所见即所得,双引号引用的内容,所见非所得。如果内容中有命令、变量等,会先把变量、命令解析出结果,然后再输出最终内容。分析到这回头看脚本密码使用了双引号导致了$2被解析成了空,最终存入数据库的密码为:abcUY。使用mysql登录时密码加单引号或手动输入密码此时$2没有被解析成空,与数据库中的密码不一致无法登录,而密码加双引号或不加时$2被解析成空,刚好和数据库的密码一致此时能正常登录数据库。

下面我们新建一个用户密码设置成:abcUY,验证一下。

mysql> create user test1@'%' identified by 'abcUY';
Query OK, 0 rows affected (0.03 sec)mysql> select user,host,authentication_string from mysql.user where user in ('app','test','test1');
+-------+------+-------------------------------------------+
| user  | host | authentication_string                     |
+-------+------+-------------------------------------------+
| app   | %    | *06E0B7BA0149152EE2A387A144A2DF9ACC492297 |
| test  | %    | *7258A15F121DD9F6F7C40C08D34A3DB5ED8C8CB5 |
| test1 | %    | *06E0B7BA0149152EE2A387A144A2DF9ACC492297 |
+-------+------+-------------------------------------------+

比较用户app与test1的authentication_string字段发现一致,说明app密码确实是abcUY 。其实不止$符会有这个问题,其它特殊字符也会存上以上问题。所以在新建用户或登录数据库时如果密码包含特殊字符需要注意是否会被解析的问题。

另外在使用login-path免密登录配置时,如果密码包含“#”符号,存在一个 bug(https://bugs.mysql.com/bug.php?id=95597)正常配置的密码无法登录到数据库,需要加上双引号。测试如下:

mysql> create user app2@'%' identified by '123#abc';
Query OK, 0 rows affected (0.01 sec)[root@node3 ~]# mysql_config_editor set --login-path=app --user=app2  --host=127.0.0.1 -p
Enter password:输入123#abc
[root@node3 ~]# mysql --login-path=app
ERROR 1045 (28000): Access denied for user 'app2'@'127.0.0.1' (using password: YES)#规避这个bug也很简单,配置时输入密码加上双引号
[root@node3 ~]# mysql_config_editor set --login-path=app --user=app2  --host=127.0.0.1 -p
Enter password: 输入"123#abc"
[root@node3 ~]# mysql --login-path=app
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 15542
Server version: 8.0.18 MySQL Community Server - GPLCopyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.mysql>

该bug在MySQL 5.7.33,MySQL 8.0.23修复。

因此,

1. 在创建密码时尽量避免使用$#等特殊字符,以免产生不必要的困扰。如果一定要使用请加上单引号或加上转义字符\。

2. 在MySQL 5.7.33与MySQL 8.0.23版本前使用login-path时密码存在"#"时,配置时输入密码需要加上双引号。

如果您认为这篇文章有些帮助,还请不吝点下文章末尾的"点赞"和"在看",或者直接转发pyq,

e6e5364ac9e621b28fc59142e57489fd.png

近期更新的文章:

《企业IT运维故障定位方法及工具》

《技术高手是如何炼成的?》

《中国民航安全运行的最强大脑》

《新书推荐 - 《MySQL高可用解决方案》》

《Oracle 23c数据库的10个特性介绍》

近期的热文:

《"红警"游戏开源代码带给我们的震撼》

文章分类和索引:

《公众号1000篇文章分类和索引》


http://www.ppmy.cn/news/402964.html

相关文章

红警自建服务器,20年前占据中国网吧的红警,现在被老外做成页游,服务器多次被挤爆!...

大家好,这里是正惊游戏,我是正惊小弟。 如果你在2000年左右进入网吧,或许你会看到这样一幅场景,在他们的电脑显示屏上,常会看到满屏闪着红光的坦克,如潮水般扑向围满了光棱塔的基地,一时间爆炸火…

红警2Linux版本

转载自:https://bbs.deepin.org/forum.php?modviewthread&tid197766&extra 下载地址:https://ws28.cn/f/3411yf6wsbh 百度网盘:链接: https://pan.baidu.com/s/1YAKOfj_HQPZu3BnYP5LfVg 密码: 1d2j 全名叫:OpenRA Rom…

红警自建服务器,有大神做了个网页版的红警2,方便打工人上班摸鱼

mumu丨文 前段时间愚人节的时候看到个游戏新闻,说是国外有个叫Chrono Divide的项目,作者用Java重写了红警2的核心程序,复刻了一个红警2页游出来。 是的,你没看错,你可以在网页上与别人联机打红警2。因为是用原版素材&a…

LeetCode-4题解 寻找两个正序数组的中位数

文章目录 LeetCode-4[题解] 寻找两个正序数组的中位数问题描述样例解析1 常规做法2 二分K-th Number解法 代码 LeetCode-4[题解] 寻找两个正序数组的中位数 问题描述 给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这…

DVPP媒体数据处理视频编码问题案例

DVPP(Digital Vision Pre-Processing)是昇腾AI处理器内置的图像处理单元,通过AscendCL媒体数据处理接口提供强大的媒体处理硬加速能力,主要功能包括图像编解码、视频编解码、图像抠图缩放等。 本期就分享几个关于DVPP视频编码问题…

RedisSon高并发分布式锁实战

Redis高并发分布式锁实战 1.分布式场景下的synchronized失效的问题–用redis实现分布式锁 synchronized是通过monitor实现的jvm级别的锁,如果是分布式系统,跑在不同的虚拟机上的tomcat上,会导致synchronized无法锁住对象 ----------- 需要分…

【Android】Room数据库的使用

简介 Room 是在 SQLite 的基础上推出的 Android 库,它是 Google 官方对数据库操作的推荐方式。使用 Room 可以更方便、高效地操作 SQLite 数据库。 使用 添加依赖 在使用 Room 之前,需要在项目中添加 Room 相关的依赖。在 build.gradle 文件中添加以…

Java 小白 重写toString()方法将如下信息输出在控制台上,红色的苹果被称为“糖心富士”,每500克4.98元,买了2500克“糖心富士”,须支付多少钱

class Apple {public String toString(){return "红色的苹果被称为“糖心富士”,每500克4.98元,买了2500克“糖心富士”,须支付多少钱";}public static void main(String[] args){System.out.println(new Apple());} }