MySQL 安全管理
- SQL 注入防护
- 访问控制与用户管理
- 权限管理
- 安全配置
SQL 注入防护
SQL 注入是应用安全中常见的问题,攻击者通过在输入中注入 SQL 片段来执行非授权的查询或操作。
防护措施:
-
使用 PreparedStatement + 绑定变量:所有数据库访问层都应使用预编译语句,将 SQL 语句的结构与数据分离,从根本上防止注入。
-
使用应用程序提供的转换函数:对用户输入使用
mysql_real_escape_string()等函数转义特殊字符。 -
自定义校验函数:对输入数据进行严格的类型、格式和长度校验,拒绝不合法的输入。
-
永远不要信任用户输入:对所有来自用户的数据进行验证和过滤。
访问控制与用户管理
MySQL 在内部保存自己的用户列表,并把每个用户与各种权限关联起来。访问控制的核心是需要给每个用户分配正确的权限,只授予账号必须的权限。
查看用户:
-- 查看所有用户
SELECT user, host FROM mysql.user;
-- 查看当前用户权限
SHOW GRANTS;
SHOW GRANTS FOR 'root'@'localhost';
创建用户:
CREATE USER 'newuser'@'localhost' IDENTIFIED BY 'password';
修改用户密码:
-- 方法1
ALTER USER 'newuser'@'localhost' IDENTIFIED BY 'newpassword';
-- 方法2
SET PASSWORD FOR 'newuser'@'localhost' = PASSWORD('newpassword');
删除用户:
DROP USER 'newuser'@'localhost';
权限管理
MySQL 的权限分为多个层次:全局权限、数据库级权限、表级权限、列级权限。
授予权限:
-- 授予特定数据库的全部权限
GRANT ALL PRIVILEGES ON mydb.* TO 'newuser'@'localhost';
-- 授予特定表的 SELECT 和 INSERT 权限
GRANT SELECT, INSERT ON mydb.mytable TO 'newuser'@'localhost';
-- 授予查询权限并允许授权给其他用户
GRANT SELECT ON mydb.* TO 'newuser'@'localhost' WITH GRANT OPTION;
撤销权限:
REVOKE SELECT, INSERT ON mydb.mytable FROM 'newuser'@'localhost';
REVOKE ALL PRIVILEGES ON mydb.* FROM 'newuser'@'localhost';
刷新权限:
FLUSH PRIVILEGES;
常用权限说明:
| 权限 | 说明 |
|---|---|
ALL PRIVILEGES |
所有权限(除 GRANT OPTION) |
SELECT |
查询权限 |
INSERT |
插入权限 |
UPDATE |
更新权限 |
DELETE |
删除权限 |
CREATE |
创建数据库和表 |
DROP |
删除数据库和表 |
ALTER |
修改表结构 |
INDEX |
创建和删除索引 |
GRANT OPTION |
授权给其他用户 |
FILE |
读写服务器文件 |
PROCESS |
查看进程信息 |
SUPER |
管理权限 |
RELOAD |
刷新日志和权限等 |
安全配置
-
正确设置目录权限:确保 MySQL 数据目录只有 MySQL 用户可以访问。
-
避免以 root 权限运行 MySQL:应该使用专门的 mysql 用户运行 mysqld。
-
删除匿名账号:MySQL 安装后默认可能存在匿名账号,应该删除。
DELETE FROM mysql.user WHERE User = '';
FLUSH PRIVILEGES;
-
给 mysql root 账号设置口令:安装后立即为 root 设置强密码。
-
设置安全密码并定期修改:使用复杂密码,不要使用弱口令。
-
只授予账号必须的权限:遵循最小权限原则,不要授予不必要的权限。
-
除 root 外,任何用户不应有 mysql 库 user 表的存取权限。
-
不要把 FILE、PROCESS 或 SUPER 权限授予管理员以外的账号:
- FILE 权限可以读写服务器文件
- PROCESS 权限可以查看进程信息
- SUPER 权限可以终止进程、修改全局变量
-
load data local 带来的安全问题:
LOAD DATA LOCAL INFILE可以读取客户端文件,存在安全风险。 -
使用 SSL:对网络传输加密,防止窃听。
-
给所有用户加上访问 IP 限制:限制用户只能从特定 IP 连接。
-- 只允许从 192.168.1.% 网段连接
CREATE USER 'appuser'@'192.168.1.%' IDENTIFIED BY 'password';
- 增加防火墙:在网络层面限制对 MySQL 端口(默认 3306)的访问。
安全相关启动选项:
| 选项 | 说明 |
|---|---|
--safe-user-create |
不允许用户使用 GRANT 创建新用户 |
--secure-auth |
不允许使用旧格式(4.1 之前)的密码 |
--skip-grant-tables |
启动时跳过权限验证(仅用于忘记密码时恢复) |
--skip-networking |
不允许 TCP/IP 连接,只允许本地连接 |
--skip-show-database |
不允许 SHOW DATABASES |
--old-passwords |
使用旧密码格式(不推荐) |