MySQL - 権限
概要
MySQLの権限システムは、データベースへのアクセスを制御し、セキュリティを維持するための基盤である。
MySQLでは、ユーザに対してグローバルレベルからカラムレベルまでの細かい粒度で権限を付与することができる。
権限は、データ操作権限、テーブル操作権限、ストアドプログラム関連権限、管理権限、レプリケーション関連権限等、多岐にわたる。
権限の付与には GRANT コマンド、削除には REVOKE コマンドを使用する。
権限情報は、mysqlデータベース内の権限テーブル (mysql.user、mysql.db、mysql.tables_priv等) に格納される。
MySQL 8.0以降では、ロール機能と動的権限が導入され、より柔軟な権限管理が可能になっている。
ロールを使用すると、複数の権限をまとめて名前付きの集合として管理でき、ユーザへの権限付与が容易になる。
動的権限は、従来のSUPER権限を細分化したもので、より細かい粒度での管理権限の制御が可能である。
権限の種類
MySQLで管理される主要な権限種類を以下に示す。
| カテゴリ | 権限名 | 説明 |
|---|---|---|
| データ操作権限 | SELECT | テーブルからデータを読み取る権限 |
| INSERT | テーブルに新しい行を挿入する権限 | |
| UPDATE | テーブルの既存データを更新する権限 | |
| DELETE | テーブルからデータを削除する権限 | |
| テーブル操作権限 | CREATE | 新しいデータベースやテーブルを作成する権限 |
| DROP | データベースやテーブルを削除する権限 | |
| ALTER | テーブルの構造を変更する権限 | |
| INDEX | インデックスを作成または削除する権限 | |
| TRUNCATE | テーブルを切り詰める権限 (MySQL 8.0.13以降、DELETE権限から分離) | |
| ストアドプログラム関連権限 | EXECUTE | ストアドプロシージャやストアドファンクションを実行する権限 |
| CREATE ROUTINE | ストアドプロシージャやストアドファンクションを作成する権限 | |
| ALTER ROUTINE | ストアドプロシージャやストアドファンクションを変更または削除する権限 | |
| TRIGGER | トリガーを作成または削除する権限 | |
| ビュー・テンポラリテーブル関連権限 | CREATE VIEW | ビューを作成する権限 |
| SHOW VIEW | ビューの定義を表示する権限 | |
| CREATE TEMPORARY TABLES | 一時テーブルを作成する権限 | |
| 管理権限 | SUPER | サーバの管理操作を実行する権限 (MySQL 8.0以降、多くの機能が動的権限に分離) |
| CREATE USER | ユーザアカウントを作成、削除、名前変更する権限 | |
| RELOAD | FLUSHコマンドを実行する権限 | |
| SHOW DATABASES | 全てのデータベースを表示する権限 | |
| PROCESS | 全てのプロセスを表示する権限 | |
| FILE | ファイルの読み書きを行う権限 (SELECT INTO OUTFILE、LOAD DATA INFILE等) | |
| SHUTDOWN | サーバをシャットダウンする権限 | |
| GRANT OPTION | 自分の権限を他のユーザに付与する権限 | |
| レプリケーション関連権限 | REPLICATION SLAVE | レプリケーションスレーブがマスターに接続する権限 |
| REPLICATION CLIENT | レプリケーションのステータスを確認する権限 | |
| ロック関連権限 | LOCK TABLES | 読み取り権限を持つテーブルに対してロックをかける権限 |
| 特殊権限 | ALL PRIVILEGES | グローバルレベルまたは指定されたレベルでの全権限 (GRANT OPTIONを除く) |
| USAGE | 権限なし (アカウントの作成時に使用) | |
| REFERENCES | 外部キーを作成する権限 (実装されていない) | |
| EVENT | イベントスケジューラのイベントを作成、変更、削除する権限 |
権限レベル
MySQLの権限は、以下に示す6つのレベルで管理される。
グローバルレベル
サーバ全体に対する権限である。
- 全てのデータベースとテーブルに適用される。
- mysql.userテーブルに格納される。
- 管理権限 (CREATE USER、SUPER、RELOAD等) はグローバルレベルでのみ付与可能
# グローバルレベルでの権限付与
GRANT SELECT, INSERT, UPDATE ON *.* TO 'user'@'host';
データベースレベル
特定のデータベースに対する権限である。
- 指定されたデータベース内の全てのオブジェクトに適用される。
- mysql.dbテーブルに格納される。
# データベースレベルでの権限付与
GRANT ALL PRIVILEGES ON my_database.* TO 'user'@'host';
テーブルレベル
特定のテーブルに対する権限である。
- 指定されたテーブル内の全てのカラムに適用される。
- mysql.tables_privテーブルに格納される。
# テーブルレベルでの権限付与
GRANT SELECT, INSERT ON my_database.my_table TO '<ユーザ名>'@'<ホスト名 または IPアドレス>';
カラムレベル
特定のカラムに対する権限である。
- SELECT、INSERT、UPDATE権限のみカラムレベルで付与可能
- mysql.columns_privテーブルに格納される。
# カラムレベルでの権限付与
GRANT SELECT (id, name), UPDATE (name) ON my_database.my_table TO '<ユーザ名>'@'<ホスト名 または IPアドレス>';
ルーチンレベル
ストアドプロシージャやストアドファンクションに対する権限である。
- EXECUTE、ALTER ROUTINE権限がルーチンレベルで付与可能
- mysql.procs_privテーブルに格納される。
# ルーチンレベルでの権限付与
GRANT EXECUTE ON PROCEDURE my_database.my_procedure TO '<ユーザ名>'@'<ホスト名 または IPアドレス>';
プロキシレベル
あるユーザが別のユーザとしてログインできる権限である。
- mysql.proxies_privテーブルに格納される。
- 主にプラグイン認証と組み合わせて使用される。
# プロキシ権限の付与
GRANT PROXY ON 'proxied_user'@'host' TO 'proxy_user'@'host';
権限テーブル
MySQLの権限情報は、mysqlデータベース内の複数のテーブルに格納される。
mysql.user
グローバルレベルの権限とユーザアカウント情報を格納する。
- ユーザ名、ホスト名、認証情報を含む。
- 全ての静的権限のグローバルレベルでの付与状態を格納する。
- アカウントリソース制限 (最大接続数、最大クエリ数等) も管理
| カラム名 | 説明 |
|---|---|
| Host | ユーザが接続できるホスト名 |
| User | ユーザ名 |
| authentication_string | 暗号化されたパスワード |
| Select_priv, Insert_priv, Update_priv, Delete_priv | 各種権限のフラグ (Y/N) |
# グローバル権限の確認
SELECT Host, User, Select_priv, Insert_priv, Update_priv, Delete_priv
FROM mysql.user
WHERE User = 'username';
mysql.db
データベースレベルの権限を格納する。
- 各ユーザが特定のデータベースに対して持つ権限を管理
| カラム名 | 説明 |
|---|---|
| Host, Db, User | 権限が適用されるホスト、データベース、ユーザ |
| Select_priv, Insert_priv, Update_priv, Delete_priv, Create_priv, Drop_priv | 各種権限のフラグ (Y/N) |
# データベースレベル権限の確認
SELECT Host, Db, User, Select_priv, Insert_priv, Create_priv
FROM mysql.db
WHERE User = 'username';
mysql.tables_priv
テーブルレベルの権限を格納する。
- 特定のテーブルに対する権限を管理
| カラム名 | 説明 |
|---|---|
| Host, Db, User, Table_name | 権限が適用されるホスト、データベース、ユーザ、テーブル |
| Table_priv | テーブルレベルの権限 (Select, Insert, Update, Delete, Create, Drop, Alter, Index等) |
| Column_priv | カラムレベルの権限が存在する場合、その権限種類 |
# テーブルレベル権限の確認
SELECT Host, Db, User, Table_name, Table_priv
FROM mysql.tables_priv
WHERE User = 'username';
mysql.columns_priv
カラムレベルの権限を格納する。
- 特定のカラムに対するSELECT、INSERT、UPDATE権限を管理
| カラム名 | 説明 |
|---|---|
| Host, Db, User, Table_name, Column_name | 権限が適用されるホスト、データベース、ユーザ、テーブル、カラム |
| Column_priv | カラムレベルの権限 (Select, Insert, Update) |
# カラムレベル権限の確認
SELECT Host, Db, User, Table_name, Column_name, Column_priv
FROM mysql.columns_priv
WHERE User = 'username';
mysql.procs_priv
ストアドプロシージャとストアドファンクションに対する権限を格納する。
- EXECUTE、ALTER ROUTINE権限を管理
| カラム名 | 説明 |
|---|---|
| Host, Db, User, Routine_name, Routine_type | 権限が適用されるホスト、データベース、ユーザ、ルーチン名、ルーチンタイプ (PROCEDURE / FUNCTION) |
| Proc_priv | ルーチンに対する権限 (Execute, Alter Routine) |
# ルーチンレベル権限の確認
SELECT Host, Db, User, Routine_name, Routine_type, Proc_priv
FROM mysql.procs_priv
WHERE User = 'username';
ロール機能 (MySQL 8.0以降)
MySQL 8.0以降では、ロール機能が導入され、複数のユーザに対して一貫した権限セットを付与することができる。
ロールは、名前付きの権限の集合であり、ユーザに付与することで権限を一括管理できる。
ロールの作成と削除
ロールの作成と削除は、以下に示すコマンドで実行する。
# ロールの作成
CREATE ROLE 'app_developer', 'app_read', 'app_write';
# ロールの削除
DROP ROLE 'app_developer';
ロールへの権限付与
ロールに対して権限を付与することで、そのロールを持つ全てのユーザが権限を継承する。
# ロールに権限を付与
GRANT SELECT, INSERT, UPDATE, DELETE ON my_database.* TO 'app_read';
GRANT CREATE, DROP, ALTER ON my_database.* TO 'app_developer';
ユーザへのロール付与
ロールをユーザに付与することで、ロールに含まれる権限がユーザに適用される。
# ユーザにロールを付与
GRANT 'app_read', 'app_write' TO 'user1'@'localhost';
# ロールをアクティブ化するにはSET ROLEコマンドを使用
SET ROLE 'app_read';
# 全ての付与されたロールをアクティブ化
SET ROLE ALL;
デフォルトロール
ユーザのログイン時に自動的にアクティブ化されるロールを設定できる。
# デフォルトロールの設定
SET DEFAULT ROLE 'app_read', 'app_write' TO 'user1'@'localhost';
# 全ての付与されたロールをデフォルトに設定
SET DEFAULT ROLE ALL TO 'user1'@'localhost';
# デフォルトロールの確認
SHOW GRANTS FOR 'user1'@'localhost' USING 'app_read';
mandatory_rolesシステム変数
全てのユーザに自動的に付与される必須ロールを設定できる。
# mandatory_rolesの設定
SET PERSIST mandatory_roles = 'role1,role2';
# 設定の確認
SELECT @@mandatory_roles;
必須ロールは、全てのユーザに自動的に付与され、ログイン時にアクティブ化される。
ユーザは必須ロールを削除またはアクティブ化解除することはできない。
動的権限 (MySQL 8.0以降)
MySQL 8.0以降では、動的権限が導入され、より細かい粒度での権限管理が可能である。
動的権限の概要
動的権限は、静的権限 (従来の権限) とは異なり、サーバの実行時に追加または削除できる権限である。
- 静的権限は、サーバのコードに固定されており、mysql.userテーブルに列として存在する。
- 動的権限は、mysql.global_grantsテーブルに格納され、柔軟に管理できる。
- MySQL 8.0以降、多くのSUPER権限の機能が個別の動的権限に分離された。
# 動的権限の付与
GRANT SYSTEM_VARIABLES_ADMIN ON *.* TO '<ユーザ名>'@'<ホスト名 または IPアドレス>';
# 動的権限の確認
SELECT * FROM mysql.global_grants WHERE User = 'username';
主要な動的権限
下表に、MySQL 8.0以降で導入された主要な動的権限を示す。
| 権限名 | 機能 | 備考 |
|---|---|---|
| SYSTEM_VARIABLES_ADMIN | グローバルシステム変数の設定と永続化 | SET PERSISTコマンドを実行する権限 |
| CONNECTION_ADMIN | 接続制限を無視してサーバに接続 | max_connectionsを超えて接続可能 |
| BACKUP_ADMIN | バックアップ操作を実行 | LOCK INSTANCE FOR BACKUP、LOCK TABLES FOR BACKUPを実行 |
| REPLICATION_SLAVE_ADMIN | レプリケーションスレーブの管理 | START SLAVE、STOP SLAVE、CHANGE MASTERコマンドを実行 |
| CLONE_ADMIN | クローン操作の管理 | CLONE INSTANCEコマンドを実行 |
| GROUP_REPLICATION_ADMIN | グループレプリケーションの管理 | START GROUP_REPLICATION、STOP GROUP_REPLICATIONを実行 |
| BINLOG_ADMIN | バイナリログの管理 | PURGE BINARY LOGS、SET sql_log_binコマンドを実行 |
| ROLE_ADMIN | ロールの管理 | WITH ADMIN OPTIONなしで付与されたロールを他のユーザに付与可能 |
| ENCRYPTION_KEY_ADMIN | 暗号化キーの管理 | ALTER INSTANCE ROTATE INNODB MASTER KEYを実行 |
| RESOURCE_GROUP_ADMIN | リソースグループの管理 | CREATE RESOURCE GROUP、ALTER RESOURCE GROUPを実行 |
| SESSION_VARIABLES_ADMIN | グローバルシステム変数の設定 | SET GLOBALで一部の制限されたシステム変数を設定可能 |
| SET_USER_ID | DEFINERの設定 | CREATE DEFINERでストアドプログラムやビューを作成可能 |
| PERSIST_RO_VARIABLES_ADMIN | 読み取り専用システム変数の永続化 | SET PERSISTで読み取り専用変数を設定可能 |
| AUDIT_ADMIN | 監査ログの設定 | 監査ログプラグインの設定を変更可能 |
# 複数の動的権限を付与
GRANT SYSTEM_VARIABLES_ADMIN, CONNECTION_ADMIN, BACKUP_ADMIN
ON *.* TO 'admin_user'@'localhost';
# 動的権限の削除
REVOKE SYSTEM_VARIABLES_ADMIN ON *.* FROM 'admin_user'@'localhost';
権限の付与
権限の付与には、GRANT コマンドを使用する。
# 基本的な構文
GRANT 権限リスト ON レベル TO 'ユーザ'@'ホスト';
# グローバルレベルでの権限付与
GRANT SELECT, INSERT, UPDATE ON *.* TO 'user1'@'localhost';
# データベースレベルでの権限付与
GRANT ALL PRIVILEGES ON my_database.* TO 'user2'@'%';
# テーブルレベルでの権限付与
GRANT SELECT, INSERT ON my_database.users TO 'user3'@'192.168.1.%';
# カラムレベルでの権限付与
GRANT SELECT (id, name, email), UPDATE (email) ON my_database.users TO 'user4'@'localhost';
# ルーチンレベルでの権限付与
GRANT EXECUTE ON PROCEDURE my_database.my_proc TO 'user5'@'localhost';
GRANT EXECUTE ON FUNCTION my_database.my_func TO 'user5'@'localhost';
# GRANT OPTIONを付与 (自分の権限を他のユーザに付与可能)
GRANT SELECT, INSERT ON my_database.* TO 'user6'@'localhost' WITH GRANT OPTION;
# ユーザの作成と同時に権限を付与
CREATE USER 'newuser'@'localhost' IDENTIFIED BY 'password';
GRANT SELECT, INSERT ON my_database.* TO 'newuser'@'localhost';
# MySQL 8.0以降 : ロールを付与
GRANT 'app_developer' TO 'user7'@'localhost';
# MySQL 8.0以降 : 動的権限を付与
GRANT SYSTEM_VARIABLES_ADMIN ON *.* TO 'admin_user'@'localhost';
ホスト指定の例を以下に示す。
'user'@'localhost'- ローカルホストからの接続のみ許可
'user'@'%'- 全てのホストからの接続を許可
'user'@'192.168.1.%'- 192.168.1.xのIPアドレスからの接続を許可
'user'@'example.com'- example.comドメインからの接続を許可
権限の確認
付与されている権限を確認するには、SHOW GRANTS コマンドを使用する。
# 現在のユーザの権限を確認
SHOW GRANTS;
# 特定のユーザの権限を確認
SHOW GRANTS FOR 'user1'@'localhost';
# ロールを含めて権限を確認 (MySQL 8.0以降)
SHOW GRANTS FOR 'user1'@'localhost' USING 'role1', 'role2';
# 現在アクティブなロールの確認 (MySQL 8.0以降)
SELECT CURRENT_ROLE();
# ユーザに付与されているロールの確認
SELECT * FROM mysql.role_edges WHERE TO_USER = 'user1';
# 動的権限の確認
SELECT * FROM mysql.global_grants WHERE User = 'user1' AND Host = 'localhost';
出力例を以下に示す。
SHOW GRANTS FOR 'user1'@'localhost';
# 出力:
# GRANT USAGE ON *.* TO `user1`@`localhost`
# GRANT SELECT, INSERT, UPDATE ON `my_database`.* TO `user1`@`localhost`
# GRANT SELECT (id, name) ON `my_database`.`users` TO `user1`@`localhost`
権限の削除
権限の削除には、REVOKE コマンドを使用する。
# 基本的な構文
REVOKE 権限リスト ON レベル FROM 'ユーザ'@'ホスト';
# グローバルレベルでの権限削除
REVOKE SELECT, INSERT ON *.* FROM 'user1'@'localhost';
# データベースレベルでの権限削除
REVOKE ALL PRIVILEGES ON my_database.* FROM 'user2'@'%';
# テーブルレベルでの権限削除
REVOKE INSERT, UPDATE ON my_database.users FROM 'user3'@'localhost';
# カラムレベルでの権限削除
REVOKE UPDATE (email) ON my_database.users FROM 'user4'@'localhost';
# GRANT OPTIONの削除
REVOKE GRANT OPTION ON my_database.* FROM 'user5'@'localhost';
# ロールの削除 (MySQL 8.0以降)
REVOKE 'app_developer' FROM 'user6'@'localhost';
# 動的権限の削除 (MySQL 8.0以降)
REVOKE SYSTEM_VARIABLES_ADMIN ON *.* FROM 'admin_user'@'localhost';
# 全ての権限を削除
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'user7'@'localhost';
権限削除後は、FLUSH PRIVILEGES コマンドを実行して権限テーブルを再読み込みすることを推奨する。
FLUSH PRIVILEGES;
様々なユースケース
運用で使用される一般的な権限設定のパターンを以下に示す。
バックアップ用ユーザ
データベースの完全バックアップを取得するために必要な権限を付与する。
# バックアップ用ユーザの作成
CREATE USER 'backup_user'@'localhost' IDENTIFIED BY 'secure_password';
# 必要な権限を付与
GRANT SELECT, RELOAD, LOCK TABLES, REPLICATION CLIENT ON *.* TO 'backup_user'@'localhost';
GRANT SHOW VIEW ON *.* TO 'backup_user'@'localhost';
GRANT PROCESS ON *.* TO 'backup_user'@'localhost';
# MySQL 8.0以降では、BACKUP_ADMIN動的権限も推奨
GRANT BACKUP_ADMIN ON *.* TO 'backup_user'@'localhost';
| 権限名 | 説明 |
|---|---|
| SELECT | データの読み取り |
| RELOAD | FLUSHコマンドの実行 |
| LOCK TABLES | テーブルのロック |
| REPLICATION CLIENT | レプリケーション状態の確認 |
| SHOW VIEW | ビュー定義の表示 |
| PROCESS | プロセスリストの表示 |
| BACKUP_ADMIN | バックアップ専用の操作 (MySQL 8.0以降) |
読み取り専用ユーザ
データの参照のみを許可し、変更を禁止するユーザを作成する。
# 読み取り専用ユーザの作成
CREATE USER 'readonly_user'@'%' IDENTIFIED BY 'secure_password';
# SELECT権限のみを付与
GRANT SELECT ON my_database.* TO 'readonly_user'@'%';
# ビューも確認できるようにする場合
GRANT SHOW VIEW ON my_database.* TO 'readonly_user'@'%';
- 特定のテーブルやカラムのみに制限する場合
# 特定のテーブルのみ参照可能 GRANT SELECT ON my_database.public_table TO 'readonly_user'@'%'; # 特定のカラムのみ参照可能 (機密情報を除外) GRANT SELECT (id, name, created_at) ON my_database.users TO 'readonly_user'@'%';
アプリケーション用ユーザ
Webアプリケーション等から使用する一般的なユーザを作成する。
# アプリケーション用ユーザの作成
CREATE USER 'app_user'@'192.168.1.%' IDENTIFIED BY 'secure_password';
# データ操作権限を付与
GRANT SELECT, INSERT, UPDATE, DELETE ON my_database.* TO 'app_user'@'192.168.1.%';
# ストアドプロシージャの実行権限を付与
GRANT EXECUTE ON my_database.* TO 'app_user'@'192.168.1.%';
# 一時テーブルの作成を許可
GRANT CREATE TEMPORARY TABLES ON my_database.* TO 'app_user'@'192.168.1.%';
# ロックを許可 (トランザクション処理で必要な場合)
GRANT LOCK TABLES ON my_database.* TO 'app_user'@'192.168.1.%';
- 接続数制限を設定する場合
# 1時間あたりの最大接続数を制限 ALTER USER 'app_user'@'192.168.1.%' WITH MAX_CONNECTIONS_PER_HOUR 1000 MAX_QUERIES_PER_HOUR 10000;
監視用ユーザ
データベースの状態監視やメトリクス収集に使用するユーザを作成する。
# 監視用ユーザの作成
CREATE USER 'monitor_user'@'localhost' IDENTIFIED BY 'secure_password';
# 必要な権限を付与
GRANT PROCESS ON *.* TO 'monitor_user'@'localhost';
GRANT REPLICATION CLIENT ON *.* TO 'monitor_user'@'localhost';
# パフォーマンススキーマへのアクセスを許可
GRANT SELECT ON performance_schema.* TO 'monitor_user'@'localhost';
# information_schemaへのアクセスを許可
GRANT SELECT ON information_schema.* TO 'monitor_user'@'localhost';
| 権限名 | 説明 |
|---|---|
| PROCESS | 実行中のプロセスリストの表示 (SHOW PROCESSLIST) |
| REPLICATION CLIENT | レプリケーション状態の確認 (SHOW MASTER STATUS、SHOW SLAVE STATUS) |
| SELECT on performance_schema | パフォーマンスメトリクスの取得 |
| SELECT on information_schema | スキーマ情報の取得 |
レプリケーション用ユーザ
MySQLレプリケーションのスレーブサーバがマスターに接続するためのユーザを作成する。
# レプリケーション用ユーザの作成
CREATE USER 'repl_user'@'%' IDENTIFIED BY 'secure_password';
# レプリケーション権限を付与
GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'%';
# MySQL 8.0以降では、REPLICATION_SLAVE_ADMIN動的権限も推奨
GRANT REPLICATION_SLAVE_ADMIN ON *.* TO 'repl_user'@'%';
- スレーブサーバでの設定例
# スレーブサーバでマスターを設定 CHANGE MASTER TO MASTER_HOST='master_host', MASTER_USER='repl_user', MASTER_PASSWORD='secure_password', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=107; START SLAVE;
セキュリティの推奨事項
権限管理におけるセキュリティの推奨事項を以下に示す。
最小権限の原則
ユーザには、業務遂行に必要な最小限の権限のみを付与する。
- グローバル権限 (*.*) は、管理ユーザ以外には付与しない。
- データベースレベル権限 (database.*)を優先的に使用する。
- 可能な限りテーブルレベルやカラムレベルで制限する。
- ALL PRIVILEGESは、本当に必要な場合のみ使用する。
# 良い例 : 必要最小限の権限
GRANT SELECT, INSERT, UPDATE ON my_database.my_table TO 'user'@'localhost';
# 悪い例 : 不必要に広い権限
GRANT ALL PRIVILEGES ON *.* TO 'user'@'%';
ホスト制限
ユーザが接続できるホストを可能な限り制限する。
- ワイルドカード (%) の使用は避け、具体的なホスト名やIPアドレスを指定する。
- アプリケーションサーバのIPアドレスのみを許可する。
- ローカル接続が必要な場合は、localhostに制限する。
# 良い例: 特定のホストのみ接続可能
CREATE USER 'user'@'192.168.1.10' IDENTIFIED BY 'password';
CREATE USER 'user'@'localhost' IDENTIFIED BY 'password';
# 悪い例: 全てのホストから接続可能
CREATE USER 'user'@'%' IDENTIFIED BY 'password';
危険な権限の組み合わせ
以下に示す権限は、セキュリティリスクが高いため、慎重に扱う必要がある。
| 権限名 | 説明 |
|---|---|
| FILE権限 | ファイルシステムへのアクセスが可能になり、機密情報の読み取りや書き込みができる。 |
| SUPER権限 (MySQL 8.0以降は動的権限に分離) | サーバの動作を変更できる強力な権限 |
| GRANT OPTION | 自分の権限を他のユーザに付与できるため、権限の拡散につながる。 |
| LOAD DATA INFILE | FILE権限が必要で、外部ファイルからデータをロードできる。 |
| SELECT INTO OUTFILE | FILE権限が必要で、クエリ結果をファイルに書き出せる。 |
# FILE権限を持つユーザは、機密ファイルを読み取り可能
SELECT LOAD_FILE('/etc/passwd');
# SUPER権限を持つユーザは、バイナリログを無効化可能
SET GLOBAL sql_log_bin = 0;
これらの権限は、管理者ユーザにのみ付与し、アプリケーション用ユーザには絶対に付与しない。
権限の定期的な監査
権限の付与状況を定期的に確認し、不必要な権限を削除する。
# 全てのユーザの権限を確認
SELECT User, Host FROM mysql.user;
# 各ユーザの権限詳細を確認
SHOW GRANTS FOR 'user'@'host';
# グローバルレベルで強力な権限を持つユーザを確認
SELECT User, Host
FROM mysql.user
WHERE Super_priv = 'Y' OR File_priv = 'Y' OR Grant_priv = 'Y';
# 動的権限を持つユーザを確認 (MySQL 8.0以降)
SELECT * FROM mysql.global_grants;
# 全てのホストから接続可能なユーザを確認
SELECT User, Host FROM mysql.user WHERE Host = '%';
定期的な監査により、以下に示す事柄を確認する。
- 不要になったユーザアカウントの削除
- 過剰な権限を持つユーザの権限縮小
- ワイルドカードホスト (%) の使用状況の確認
- パスワードの有効期限と強度の確認
# 不要なユーザの削除
DROP USER 'old_user'@'localhost';
# パスワードポリシーの確認
SHOW VARIABLES LIKE 'validate_password%';
# パスワードの有効期限を設定
ALTER USER 'user'@'host' PASSWORD EXPIRE INTERVAL 90 DAY;