MySQL 權限系統基於授權表(user、db、tables_priv、columns_priv、procs_priv)實現多層級存取控制。理解授權表生效時機、權限檢查順序、危險權限識別與最小權限落地,是構建安全資料庫環境的基石。本文系統重構官方文檔授權原則,補充實戰避坑指南。
| 場景 | 生效時機 | 影響範圍 | 操作範例 |
|---|---|---|---|
| 服務啟動 | 啟動時讀入記憶體 | 全域 | systemctl start mysqld |
| GRANT/REVOKE/SET PASSWORD | **立即生效** | 當前會話 + 新會話 | GRANT SELECT ON db.* TO 'u'@'%'; |
| 直接修改授權表 (INSERT/UPDATE/DELETE) | 需 FLUSH PRIVILEGES 或重啟 | 全域 | UPDATE user SET Password=...; FLUSH PRIVILEGES; |
| 現有連線 | 見下表 | 增量 | -- |
| 權限層級 | 生效時機 | 說明 |
|---|---|---|
| 表/欄權限 | **下一次請求** | 即時生效 |
| 資料庫權限 | 下一個 USE db_name | 需切換庫 |
| 全域權限/密碼 | **下一次重新連線** | 現有連線不受影響 |
user:全域權限、帳號認證資訊(Host、User、Password、全域權限欄位)db:資料庫級權限(Host、Db、User、權限欄位)tables_priv:表級權限columns_priv:欄位級權限procs_priv:存儲過程/函數權限1. user 表全域權限 → 若滿足,直接通過
2. db 表資料庫權限 → Host+Db+User 匹配
3. tables_priv 表權限 → Host+Db+User+Table 匹配
4. columns_priv 欄位權限 → Host+Db+User+Table+Column 匹配
5. procs_priv 程序權限 → Host+Db+User+Routine 匹配
mysql.user 等)**嚴禁授予非 root 帳號 ANY 權限**DELETE FROM mysql.user WHERE User = '';
DELETE FROM mysql.db WHERE User = '';
DELETE FROM mysql.tables_priv WHERE User = '';
DELETE FROM mysql.columns_priv WHERE User = '';
FLUSH PRIVILEGES;
匿名帳號允許任意用戶名無密碼連線,極高風險。
ALTER USER 'root'@'localhost' IDENTIFIED BY 'StrongRootPass@2024';
-- 刪除遠端 root
DELETE FROM mysql.user WHERE User = 'root' AND Host != 'localhost';
FLUSH PRIVILEGES;
validate_password 強密碼策略% 通配符主機名(除非極少數受控場景)| 權限 | 風險等級 | 風險描述 | 管控建議 |
|---|---|---|---|
| GRANT OPTION | 🔴 高 | 可將自身權限轉授他人,權限傳遞鏈失控 | 僅 DBA 持有 |
| ALTER | 🔴 高 | 可 RENAME TABLE 繞過權限(將無權表改名為有權表) | 僅 DBA/遷移帳號 |
| SHUTDOWN | 🔴 高 | 可關閉資料庫服務,拒絕服務攻擊 | 僅 DBA/監控帳號 |
| PROCESS | 🟠 中 | 可見所有執行中 SQL(含敏感參數、密碼) | 僅 DBA/監控帳號 |
| FILE | 🔴 極高 | 任意讀寫 Server 檔案系統(/etc/passwd、私鑰、資料檔) | **嚴禁非 DBA**,secure_file_priv 限制目錄 |
| SUPER | 🔴 極高 | KILL 連線、修改全域變數、控制複寫、CHANGE MASTER TO | 僅 DBA/複寫帳號 |
| CREATE USER | 🟠 中 | 可建立新帳號 | 僅 DBA/自動化平台 |
| RELOAD | 🟡 低 | FLUSH PRIVILEGES/LOGS/TABLES | DBA/備份帳號 |
-- 攻擊者擁有 FILE 權限
-- 1. 建立惡意表
CREATE TABLE steal (data LONGBLOB);
-- 2. 竊取系統敏感檔
LOAD DATA INFILE '/etc/passwd' INTO TABLE steal
FIELDS ESCAPED BY '' LINES TERMINATED BY '';
SELECT * FROM steal;
-- 3. 竊取其他資料庫表結構與數據
LOAD DATA INFILE './other_db/t.frm' INTO TABLE steal ...;
SELECT * FROM steal INTO OUTFILE './attacker_db/t.frm' ...;
LOAD DATA INFILE './other_db/t.MYD' INTO TABLE steal ...;
SELECT * FROM steal INTO OUTFILE './attacker_db/t.MYD' ...;
LOAD DATA INFILE './other_db/t.MYI' INTO TABLE steal ...;
SELECT * FROM steal INTO OUTFILE './attacker_db/t.MYI' ...;
-- 結果:攻擊者獲得完整表副本,可離線分析
MAX_EXECUTION_TIME (5.7.8+)、Resource Group (8.0+)DEFINER 繞過CREATE USER 'app_rw'@'10.0.1.%' IDENTIFIED BY 'AppRwPass@2024';
GRANT SELECT, INSERT, UPDATE, DELETE ON `biz_db`.* TO 'app_rw'@'10.0.1.%';
-- 不授予:DROP, ALTER, INDEX, CREATE, GRANT, FILE, SUPER, PROCESS, SHUTDOWN
CREATE USER 'app_ro'@'10.0.2.%' IDENTIFIED BY 'AppRoPass@2024';
GRANT SELECT ON `biz_db`.* TO 'app_ro'@'10.0.2.%';
-- 配合 MAX_EXECUTION_TIME 限制長查詢
ALTER USER 'app_ro'@'10.0.2.%' WITH MAX_EXECUTION_TIME 30000; -- 30秒
CREATE USER 'backup'@'10.0.3.%' IDENTIFIED BY 'BackupPass@2024';
GRANT SELECT, RELOAD, LOCK TABLES, SHOW VIEW, EVENT, TRIGGER ON *.* TO 'backup'@'10.0.3.%';
-- mysqldump --single-transaction 需 RELOAD (FLUSH TABLES WITH READ LOCK)
CREATE USER 'repl'@'10.0.4.%' IDENTIFIED BY 'ReplPass@2024';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'10.0.4.%';
-- 僅需此權限,無其他任何權限
-- 1. 全帳號權限掃描
SELECT User, Host,
GROUP_CONCAT(privilege_type) AS global_privs
FROM information_schema.user_privileges
GROUP BY User, Host;
-- 2. 危險權限持有者掃描
SELECT User, Host FROM mysql.user WHERE Super_priv = 'Y' OR File_priv = 'Y' OR Grant_priv = 'Y';
-- 3. 定期收回過期權限(腳本化)
-- 原則:人員離職/轉崗即日收回、專案下線即日收回、半年未使用收回
MySQL 授權體系雖非強制存取控制 (MAC) 級別,但透過**授權表分層、生效機制精準控制、危險權限嚴格隔離、最小權限模板化落地、持續審計清理**,可構建企業級安全基線。核心原則:**權限隨業務最小化、帳號隨網段最小化、密碼隨策略強化、操作隨審計可追溯**。