MySQL 權限系統基於 `mysql` 系統庫中的五張授權表,按粒度從粗到細分層:
| 表名 | 粒度 | 核心範圍列 | 權限列示例 |
|---|---|---|---|
user | 全局/實例級 | Host, User, Password | Select_priv, Insert_priv, ..., Super_priv, File_priv |
db | 數據庫級 | Host, Db, User | Select_priv, Create_priv, Drop_priv, Grant_priv |
host | 主機+數據庫級 | Host, Db | 同 db 表,不受 GRANT/REVOKE 影響 |
tables_priv | 表級 | Host, Db, User, Table_name | Table_priv (set), Column_priv (set) |
columns_priv | 列級 | Host, Db, User, Table_name, Column_name | Column_priv (set: Select, Insert, Update, References) |
Host 支持 `%`、`_` 通配符、CIDR (如 `192.168.1.0/255.255.255.0`);User 為空匹配匿名用戶。GRANT ALL PRIVILEGES ON *.* TO 'admin'@'localhost' IDENTIFIED BY 'Str0ngP@ss' WITH GRANT OPTION;
FLUSH PRIVILEGES;
CREATE USER 'app_user'@'192.168.10.%' IDENTIFIED BY 'AppP@ss2024';
GRANT SELECT, INSERT, UPDATE, DELETE, EXECUTE ON `app_db`.* TO 'app_user'@'192.168.10.%';
-- 拒絕 DDL、GRANT、FILE 等高危權限
FLUSH PRIVILEGES;
INSERT INTO `user` (Host, User, authentication_string, Select_priv, Insert_priv, Update_priv, Delete_priv, Create_priv, Drop_priv, Grant_priv, Super_priv)
VALUES ('192.168.10.%', 'app_user', PASSWORD('AppP@ss2024'), 'Y','Y','Y','Y','N','N','N','N');
INSERT INTO `db` (Host, Db, User, Select_priv, Insert_priv, Update_priv, Delete_priv, Create_priv, Drop_priv)
VALUES ('192.168.10.%', 'app_db', 'app_user', 'Y','Y','Y','Y','N','N');
FLUSH PRIVILEGES;
REVOKE ALL PRIVILEGES ON `app_db`.* FROM 'app_user'@'192.168.10.%';
DELETE FROM `user` WHERE User='app_user' AND Host='192.168.10.%';
FLUSH PRIVILEGES;
注意:`REVOKE` 不刪除用戶行,必須手工 `DELETE FROM user` 並 `FLUSH PRIVILEGES` 徹底清理。
| 語言/框架 | 核心防禦 API | 關鍵原則 |
|---|---|---|
| 通用 Web | — | 永不信任用戶輸入;數值型參數用預編譯/參數化;長度/格式/業務規則雙端校驗 |
| PHP | mysqli::prepare / PDO::prepare | 禁用 `mysql_*` 舊 API;`addslashes` 不可靠,必須用驅動層參數化 |
| Java (JDBC) | PreparedStatement | 拒絕 `Statement` 拼接;連接池啟用 `cachePreStmts=true` |
| .NET (ADO.NET) | SqlCommand.Parameters | 嚴禁字符串拼接 SQL;`AddWithValue` 注意類型推斷陷阱 |
| Perl (DBI) | $dbh->prepare + execute(@params) | 使用 `quote()` 僅作為最後手段 |
| Python (DB-API) | cursor.execute(sql, params) | 參數佔位符 `%s` (PyMySQL) / `?` (sqlite3) / `%s` (psycopg2) |
| 參數 | 作用 | 建議場景 |
|---|---|---|
--skip-grant-tables | 跳過權限檢查,緊急重置 root 密碼 | 僅維護窗口,臨時使用,用畢即移除 |
--skip-show-database | 非 SUPER 權限用戶不可 `SHOW DATABASES` | 生產環境強制開啟 |
--chroot=/path | 限制 `LOAD DATA INFILE`/`SELECT ... INTO OUTFILE` 路徑 | 高安全合規環境,需確保 `/path/tmp` 可寫建立 socket |
--log-slow-queries=/path/slow.log | 記錄超過 `long_query_time` 的 SQL | 生產常態開啟,配合 `pt-query-digest` 定期分析 |
--skip-networking | 禁用 TCP/IP,僅允許 Unix Socket 本地連接 | 應用與數據庫同機、極高安全要求 |
FLUSH PRIVILEGES; ALTER USER 'root'@'localhost' IDENTIFIED BY 'NewStr0ngP@ss'; (5.7.6+) 或 UPDATE user SET authentication_string=PASSWORD('...') WHERE User='root'; FLUSH PRIVILEGES;。MySQL 權限模型雖顯老舊,但通過「最小權限原則 + 參數化編程 + 安全啟動參數 + 審計日誌」四層防線,可構建符合等保三級/PCI-DSS 要求的數據庫安全基線。建議將授權變更納入變更管理流程,定期 `pt-show-grants` 導出權限快照審計。