快速掌握 MySQL 授權表運維注意事項

普通用戶有MySQL鑑權表的訪問權限帶來的風險。

作者:餘振興,愛可生 DBA 團隊成員,熱衷技術分享、編寫技術文檔。

愛可生開源社區出品,原創內容未經授權不得隨意使用,轉載請聯繫小編並註明來源。

本文共 1100 字,預計閱讀需要 3 分鐘。

基礎背景

我們在做權限授權時需要給到應用用戶增刪改查權限,比如下面的授權語句。這樣的好處是當實例創建多個業務庫時,無需再次給新的業務庫授權,該權限默認對所有庫有增刪改查權限,主打一個方便,但實際這種授權方式會帶來較大的權限風險,甚至導致數據庫被攻擊破壞。

create user 'app'@'%' identified by 'app';
grant select,update,delete,insert on *.* to 'app'@'%';

演示驗證

我們基於以上的授權來做一個業務用戶 提權(自己給自己增加額外的權限)操作,下面是操作的時序表格(建議 PC 端查看)。

場景1

管理用戶觸發 flush privileges 刷新內存授權表觸發提權。

操作/用戶 root 用戶 app 用戶
登錄 mysql -S /data/mysql/3306/data/mysqld.sock mysql -h127.0.0.1 -uapp -papp -P3306
app 用戶給自己提權。這裏,update 成功了,但由於缺少 reload 或 super 權限,導致刷新到內存中失敗了。 mysql> update mysql.user set Select_priv='Y',Insert_priv='Y',Update_priv='Y',Delete_priv='Y',Create_priv='Y',Drop_priv='Y',Reload_priv='Y',Shutdown_priv='Y',Process_priv='Y',File_priv='Y',Grant_priv='Y',References_priv='Y',Index_priv='Y',Alter_priv='Y',Show_db_priv='Y',Super_priv='Y',Lock_tables_priv='Y' where user='app' and host='%';<br><br>Query OK, 1 row affected (0.01 sec)<br>Rows matched: 1 Changed: 1 Warnings: 0<br><br>mysql> flush privileges;<br>ERROR 1227 (42000): Access denied; you need (at least one of) the RELOAD privilege(s) for this operation
重啓數據庫 mysql> flush privileges;<br>Query OK, 0 rows affected (0.00 sec)
app 用戶重新登錄數據庫查看自己的權限,提權成功。 mysql> show grants\G<br>*************************** 1. row ***************************<br>Grants for app@%: GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, LOCK TABLES ON . TO app@% WITH GRANT OPTION<br>1 row in set (0.00 sec)

場景2

重啓數據庫重新加載授權表到內存觸發提權。

操作/用戶 root 用戶 app 用戶
登錄 mysql -S /data/mysql/3306/data/mysqld.sock mysql -h127.0.0.1 -uapp -papp -P3306
app用戶給自己提權,這裏,update成功了,但由於缺少reload或super權限,導致刷新到內存中失敗了。 mysql> update mysql.user set Select_priv='Y',Insert_priv='Y',Update_priv='Y',Delete_priv='Y',Create_priv='Y',Drop_priv='Y',Reload_priv='Y',Shutdown_priv='Y',Process_priv='Y',File_priv='Y',Grant_priv='Y',References_priv='Y',Index_priv='Y',Alter_priv='Y',Show_db_priv='Y',Super_priv='Y',Lock_tables_priv='Y' where user='app' and host='%';<br><br>Query OK, 1 row affected (0.01 sec)<br>Rows matched: 1 Changed: 1 Warnings: 0<br><br>mysql> flush privileges;<br>ERROR 1227 (42000): Access denied; you need (at least one of) the RELOAD privilege(s) for this operation
重啓數據庫 mysql> restart;<br>Query OK, 0 rows affected (0.00 sec)
app 用戶重新登錄數據庫查看自己的權限,提權成功。 mysql> show grants\G<br>*************************** 1. row ***************************<br>Grants for app@%: GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, LOCK TABLES ON . TO app@% WITH GRANT OPTION<br>1 row in set (0.00 sec)

場景總結

  • 給普通用戶授予 MySQL 鑑權相關表的權限均會帶來風險
    • 備註:鑑權表除了 user 表,還包括 dbcolumns_privtables_privprocs_privproxies_priv 表。
  • 即使只對鑑權表授予只讀權限,如 user 表,也會被獲取到 authentication_string 字段的密文串,通過其他方式做密碼庫匹配破解。
    • 曾經遇到過一個場景,普通用戶僅有 user 的查詢權限,其通過查詢該表信息發現 root@localhost 用戶密碼爲空,於是直接用 root 用戶訪問數據庫,類似於進行了提權操作。

規避方式

  • 不要對非管理員用戶授予任何鑑權表的訪問權限,即使是隻讀權限。
  • 授權遵循最小權限原則。
  • MySQL 8.0 增加了回收部分權限的參數 partial_revokes,可單獨將 mysql 庫的權限回收。示例如下:
-- 創建app用戶並授予所有數據庫增刪改查權限
create user 'app'@'%' identified by 'app';
grant select,update,delete,insert on *.* to 'app'@'%';

-- 開啓部分權限回收的參數
set global partial_revokes=on;

-- 單獨回收app用戶對mysql庫的權限
revoke select,update,delete,insert on mysql.* from 'app'@'%';

-- 查看當前app用戶的授權信息
-- 這裏的權限是以交集的形式存在,必須兩者都滿足
show grants for app;
+-------------------------------------------------------------------+
| Grants for app@%                                                  |
+-------------------------------------------------------------------+
| GRANT SELECT, INSERT, UPDATE, DELETE ON *.* TO `app`@`%`          |
| REVOKE SELECT, INSERT, UPDATE, DELETE ON `mysql`.* FROM `app`@`%` |
+-------------------------------------------------------------------+

-- 以app用戶登錄數據庫訪問mysql.user表,報錯無權限
mysql> select user,host from mysql.user;
ERROR 1142 (42000): SELECT command denied to user 'app'@'127.0.0.1' for table 'user'

更多技術文章,請訪問:https://opensource.actionsky.com/

關於 SQLE

SQLE 是一款全方位的 SQL 質量管理平臺,覆蓋開發至生產環境的 SQL 審覈和管理。支持主流的開源、商業、國產數據庫,爲開發和運維提供流程自動化能力,提升上線效率,提高數據質量。

SQLE 獲取

類型 地址
版本庫 https://github.com/actiontech/sqle
文檔 https://actiontech.github.io/sqle-docs/
發佈信息 https://github.com/actiontech/sqle/releases
數據審覈插件開發文檔 https://actiontech.github.io/sqle-docs/docs/dev-manual/plugins/howtouse
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章