普通用戶有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
表,還包括db
、columns_priv
、tables_priv
、procs_priv
、proxies_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 審覈和管理。支持主流的開源、商業、國產數據庫,爲開發和運維提供流程自動化能力,提升上線效率,提高數據質量。