Appearance
第15章:MySQL 安全防护(实战必备)
MySQL 安全是数据库管理的重要组成部分,本章将介绍如何保护 MySQL 数据库免受常见安全威胁,包括 SQL 注入攻击、权限管理和数据备份。
15.1 SQL注入攻击(重点,必防)
15.1.1 SQL注入的危害
SQL 注入是一种常见的网络攻击方式,攻击者通过在用户输入中插入恶意 SQL 代码,从而绕过应用程序的验证,执行未授权的数据库操作。
常见危害:
- 恶意篡改数据
- 删除数据库表
- 获取敏感信息(如密码)
- 执行服务器命令
- 完全控制数据库服务器
15.1.2 防范方法
1. 参数化查询
使用预处理语句和参数化查询,避免直接拼接 SQL 语句:
错误示例:
sql
-- 直接拼接用户输入,容易遭受 SQL 注入
$username = $_POST['username'];
$password = $_POST['password'];
$sql = "SELECT * FROM users WHERE username = '$username' AND password = '$password'";正确示例(使用参数化查询):
php
// PHP PDO 示例
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = ? AND password = ?");
$stmt->execute([$username, $password]);
// MySQLi 示例
$stmt = $mysqli->prepare("SELECT * FROM users WHERE username = ? AND password = ?");
$stmt->bind_param("ss", $username, $password);
$stmt->execute();2. 过滤特殊字符
对用户输入进行过滤和转义:
php
// PHP 示例
$username = mysqli_real_escape_string($conn, $_POST['username']);
$password = mysqli_real_escape_string($conn, $_POST['password']);
$sql = "SELECT * FROM users WHERE username = '$username' AND password = '$password'";3. 最小权限原则
为数据库用户分配最小必要的权限:
sql
-- 创建只具有 SELECT 权限的用户
CREATE USER 'readonly'@'localhost' IDENTIFIED BY 'password';
GRANT SELECT ON database.* TO 'readonly'@'localhost';
-- 创建具有 CRUD 权限的用户
CREATE USER 'appuser'@'localhost' IDENTIFIED BY 'password';
GRANT SELECT, INSERT, UPDATE, DELETE ON database.* TO 'appuser'@'localhost';4. 输入验证
在应用程序层面进行输入验证:
- 检查输入长度
- 检查输入格式
- 使用白名单验证
- 过滤特殊字符
5. 加密敏感数据
对敏感数据进行加密存储:
sql
-- 使用 MD5 加密(不推荐,已被破解)
INSERT INTO users (username, password) VALUES ('admin', MD5('password'));
-- 使用 SHA256 加密
INSERT INTO users (username, password) VALUES ('admin', SHA2('password', 256));
-- 推荐使用专门的密码哈希函数
-- 在应用程序中使用 password_hash() 等函数15.2 数据库权限管理(新手了解)
15.2.1 用户管理
创建用户:
sql
-- 创建本地用户
CREATE USER 'username'@'localhost' IDENTIFIED BY 'password';
-- 创建远程用户
CREATE USER 'username'@'%' IDENTIFIED BY 'password';
-- 创建指定 IP 用户
CREATE USER 'username'@'192.168.1.100' IDENTIFIED BY 'password';修改用户密码:
sql
-- MySQL 5.7+
ALTER USER 'username'@'localhost' IDENTIFIED BY 'new_password';
-- MySQL 5.6 及以下
SET PASSWORD FOR 'username'@'localhost' = PASSWORD('new_password');删除用户:
sql
DROP USER 'username'@'localhost';15.2.2 权限管理
授权:
sql
-- 授予所有权限
GRANT ALL PRIVILEGES ON *.* TO 'username'@'localhost' WITH GRANT OPTION;
-- 授予指定数据库权限
GRANT ALL PRIVILEGES ON database.* TO 'username'@'localhost';
-- 授予指定表权限
GRANT SELECT, INSERT, UPDATE ON database.table TO 'username'@'localhost';
-- 授予列级权限
GRANT SELECT (id, name), UPDATE (name) ON database.table TO 'username'@'localhost';查看权限:
sql
-- 查看当前用户权限
SHOW GRANTS;
-- 查看指定用户权限
SHOW GRANTS FOR 'username'@'localhost';撤销权限:
sql
-- 撤销所有权限
REVOKE ALL PRIVILEGES ON *.* FROM 'username'@'localhost';
-- 撤销指定权限
REVOKE SELECT, INSERT ON database.* FROM 'username'@'localhost';
-- 刷新权限
FLUSH PRIVILEGES;权限级别:
| 权限 | 作用 | 适用对象 |
|---|---|---|
ALL | 所有权限 | 全局/数据库/表 |
SELECT | 查询数据 | 表/列 |
INSERT | 插入数据 | 表/列 |
UPDATE | 更新数据 | 表/列 |
DELETE | 删除数据 | 表 |
CREATE | 创建对象 | 数据库/表/索引 |
DROP | 删除对象 | 数据库/表/索引 |
ALTER | 修改表结构 | 表 |
GRANT OPTION | 授予权限 | 全局/数据库/表 |
15.3 数据库备份与恢复(核心,防止数据丢失)
15.3.1 备份方法
1. 使用 mysqldump 命令
bash
-- 备份整个数据库
mysqldump -u root -p database > backup.sql
-- 备份单个表
mysqldump -u root -p database table1 table2 > backup.sql
-- 备份多个数据库
mysqldump -u root -p --databases db1 db2 > backup.sql
-- 备份所有数据库
mysqldump -u root -p --all-databases > all_backup.sql
-- 压缩备份
mysqldump -u root -p database | gzip > backup.sql.gz2. 使用可视化工具
- phpMyAdmin:导出功能
- Navicat:备份功能
- DBeaver:导出功能
3. 自动备份脚本
创建定时备份脚本:
bash
#!/bin/bash
# 配置
DB_USER="root"
DB_PASS="password"
DB_NAME="database"
BACKUP_DIR="/backup"
DATE=$(date +%Y%m%d_%H%M%S)
# 创建备份目录
mkdir -p $BACKUP_DIR
# 执行备份
mysqldump -u $DB_USER -p$DB_PASS $DB_NAME > $BACKUP_DIR/${DB_NAME}_${DATE}.sql
# 压缩备份
gzip $BACKUP_DIR/${DB_NAME}_${DATE}.sql
# 删除7天前的备份
find $BACKUP_DIR -name "${DB_NAME}_*.sql.gz" -mtime +7 -delete
echo "Backup completed: $BACKUP_DIR/${DB_NAME}_${DATE}.sql.gz"15.3.2 恢复方法
1. 使用 SOURCE 命令
sql
-- 登录 MySQL
mysql -u root -p
-- 创建数据库(如果不存在)
CREATE DATABASE IF NOT EXISTS database;
-- 使用数据库
USE database;
-- 恢复数据
SOURCE /path/to/backup.sql;2. 使用 mysql 命令
bash
-- 恢复数据库
mysql -u root -p database < backup.sql
-- 恢复压缩备份
gunzip < backup.sql.gz | mysql -u root -p database3. 使用可视化工具
- phpMyAdmin:导入功能
- Navicat:还原功能
- DBeaver:导入功能
15.3.3 备份策略
推荐备份策略:
| 备份类型 | 频率 | 保留时间 | 适用场景 |
|---|---|---|---|
| 完整备份 | 每天 | 7-30天 | 所有数据库 |
| 增量备份 | 每小时 | 24-48小时 | 大型数据库 |
| 差异备份 | 每周 | 1-2个月 | 中等大小数据库 |
备份注意事项:
- 定期测试备份的恢复功能
- 存储备份到多个位置
- 加密敏感数据备份
- 建立备份监控机制
15.4 其他安全措施
15.4.1 网络安全
- 限制远程访问:只允许特定 IP 访问 MySQL
- 使用 SSL:启用 MySQL SSL 连接
- 防火墙:配置防火墙规则,只开放必要端口
- 更改默认端口:修改 MySQL 默认端口 3306
15.4.2 系统安全
- 定期更新:及时更新 MySQL 版本
- 关闭不必要服务:禁用不需要的 MySQL 功能
- 监控日志:定期检查 MySQL 错误日志和访问日志
- 审计:启用 MySQL 审计功能
15.4.3 应用安全
- 使用 ORM:使用对象关系映射框架,如 PDO、MyBatis 等
- 输入验证:严格验证所有用户输入
- 错误处理:不向用户显示详细的错误信息
- 会话管理:安全管理用户会话
15.5 安全检查清单
| 检查项 | 状态 | 说明 |
|---|---|---|
| 使用参数化查询 | ✅ | 防止 SQL 注入 |
| 最小权限原则 | ✅ | 限制用户权限 |
| 定期备份 | ✅ | 防止数据丢失 |
| 密码加密 | ✅ | 保护敏感数据 |
| 网络安全 | ✅ | 限制访问 |
| 系统更新 | ✅ | 修复安全漏洞 |
| 输入验证 | ✅ | 防止恶意输入 |
| 日志监控 | ✅ | 检测异常行为 |
15.6 本章小结
| 安全措施 | 作用 | 优先级 |
|---|---|---|
| SQL 注入防范 | 防止恶意攻击 | 高 |
| 权限管理 | 限制操作范围 | 高 |
| 数据备份 | 防止数据丢失 | 高 |
| 网络安全 | 保护访问安全 | 中 |
| 系统安全 | 加固系统防护 | 中 |
| 应用安全 | 增强应用防护 | 中 |
安全原则:
- 深度防御:多层次安全措施
- 最小权限:只授予必要的权限
- 定期审计:定期检查安全配置
- 持续更新:及时更新安全补丁
- 备份优先:数据安全第一
安全是一个持续的过程,需要定期检查和更新安全措施,以应对不断演变的安全威胁。
