Skip to content

第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.gz

2. 使用可视化工具

  • 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 database

3. 使用可视化工具

  • 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 注入防范防止恶意攻击
权限管理限制操作范围
数据备份防止数据丢失
网络安全保护访问安全
系统安全加固系统防护
应用安全增强应用防护

安全原则:

  • 深度防御:多层次安全措施
  • 最小权限:只授予必要的权限
  • 定期审计:定期检查安全配置
  • 持续更新:及时更新安全补丁
  • 备份优先:数据安全第一

安全是一个持续的过程,需要定期检查和更新安全措施,以应对不断演变的安全威胁。

© 2026 编程马·菜鸟教程 版权所有