ホームページ >データベース >mysql チュートリアル >MySQL セキュリティ ガイド (2) (リダイレクト)
MySQL セキュリティガイド (2)
2.1.3 データベースとテーブルの権限
次の権限はデータベースとテーブルの操作に適用されます。
ALTER
を使用すると、ALTER を使用できます
TABLE ステートメント、これは実際には単純な第 1 レベルの権限です。データベースに対して実行する操作に応じて、他の権限が必要です。
CREATE
を使用すると、データベースとテーブルを作成できますが、インデックスは作成できません。
DELETE
を使用すると、テーブルから既存のレコードを削除できます。
DROP
を使用すると、データベースとテーブルを削除 (破棄) できますが、インデックスは削除できません。
INDEX
を使用すると、インデックスを作成および削除できます。
参考資料
現在は使用されていません。
SELECT
を使用すると、SELECT ステートメントを使用してテーブルからデータを取得できます。 SELECT NOW() や SELECT 4/2 など、テーブルを含まない SELECT ステートメントの場合は必要ありません。
UPDATE
を使用すると、テーブル内の既存のレコードを変更できます。
2.1.4
管理権限
次の権限は、サーバーの操作またはユーザー認証機能を制御する管理操作に使用されます。
FILE
を使用すると、サーバーホスト上のファイルの読み取りまたは書き込みをサーバーに指示できます。この権限は安易に付与すべきではありません。危険です。「権限テーブルのリスクの回避」を参照してください。サーバーは、この権限を制限内に保つためにある程度の注意を払います。誰でも読み取り可能なファイルのみを読み取ることができます。書き込み中のファイルは存在してはなりません。これにより、/etc/passwd や他の人のデータベースに属するデータ ディレクトリなどの重要なファイルをサーバーに強制的に書き換えることができなくなります。
ファイル権限を付与する場合は、サーバーを UNIX root ユーザーとして実行していないことを確認してください。これは、root はファイル システムのどこにでも新しいファイルを作成できるためです。サーバーを特権のないユーザーとして実行する場合、サーバーはユーザーがアクセスできるディレクトリにのみファイルを作成できます。
GRANT
を使用すると、GRANT を含む自分の権限を他の人に付与できます。
PROCESS
を使用すると、SHOWを使用できます
PROCESS ステートメントまたは mysqladmin process コマンドを使用して、サーバー内で実行されているスレッド (プロセス) に関する情報を表示します。この権限により、KILL ステートメントまたは mysqladmin の使用も許可されます。
kill コマンドはスレッドを強制終了します。
いつでも自分のスレッドを表示したり、強制終了したりできます。 PROCESS 権限により、任意のスレッドでこれらの操作を実行できるようになります。
RELOAD
を使用すると、幅広いサーバー管理操作を実行できます。 FLUSH ステートメントを発行できます。また、mysqladmin の reload、refresh、flush-hosts、flush-logs、flush-privileges、および flash-tables コマンドを参照することもできます。
SHUTDOWN
を使用すると、mysqladmin shutdown を使用してサーバーをシャットダウンできます。
user、db、host テーブルでは、各権限は個別の列で指定されます。これらの列はすべて ENUM ("N", "Y") 型として宣言されているため、各重みのデフォルト値は "N" です。 tables_priv および columns_priv の権限は SET によって表され、単一の列と任意の組み合わせで権限を指定できます。これら 2 つのテーブルは他の 3 つのテーブルより新しいため、より効率的な表現が使用されます。 (将来的には、user、db、および host テーブルも SET タイプで表される可能性があります。)
tables_priv テーブルの Table_priv 列は、次のように定義されます:
SET('Select','Insert' ,'Update',' Delete','Create','Drop','Grant','References','Index','Alter')
coloums_priv テーブルの Column_priv 列は次のように定義されます。
SET('Select','Insert','Update','References')
列レベルの権限が少ない方が合理的であるため、列権限はテーブル権限よりも低くなります。たとえば、テーブルを作成することはできますが、独立した列を作成することはできません。
ユーザー テーブルには、他の認可テーブルに存在しない特定の権限列 (File_priv、Process_priv、Reload_priv、Shutdown_priv) が含まれています。これらの権限は、特定のデータベースやテーブルに関連しない、サーバーに実行を要求する操作に適用されます。現在のデータベースの内容に基づいてユーザーがデータベースを閉じることを許可するのは意味がありません。
2.2
サーバーがクライアント アクセスを制御する方法
MySQL を使用する場合、クライアント アクセス制御には 2 つの段階があります。最初のフェーズは、サーバーに接続しようとしたときに発生します。サーバーはユーザー テーブルを調べて、ユーザーの名前、接続元のホスト、および指定したパスワードに一致するエントリが見つかるかどうかを確認します。一致しない場合は接続できません。一致するものがあれば、接続を確立し、第 2 フェーズに進みます。このフェーズでは、発行するクエリごとに、サーバーは認証テーブルをチェックして、クエリを実行するための十分な権限があるかどうかを確認します。第 2 フェーズは、サーバーとの会話が終了するまで続きます。
このセクションでは、MySQL サーバーが認証テーブルのエントリを受信した接続リクエストまたはクエリと照合するために使用する原則について詳しく説明します。これには、認証テーブルの範囲列の正当な値の種類、権限情報を組み合わせる方法が含まれます。権限テーブルとエントリがチェックされる順序。
2.2.1
範囲列の内容
一部の範囲列にはリテラル値が必要ですが、ほとんどの列ではワイルドカードまたはその他の特別な値が許可されます。
ホスト
[ホスト] 列の値には、ホスト名または IP アドレスを指定できます。値 localhost はローカルホストを意味しますが、ホスト名を使用した場合ではなく、ローカルホストのホスト名を使用した場合にのみ一致します。ローカル ホスト名が pig.snake.net で、ユーザー テーブルに 2 つのレコードがあり、1 つはホスト値または localhost で、もう 1 つは pig.snake.net である場合、localhost のレコードは次のように扱われます。これは localhost に接続した場合に一致し、その他は pig.snake.net に接続した場合にのみ一致します。クライアントが 2 つの方法で接続できるようにするには、ユーザー テーブルに 2 つのレコードが必要です。
ワイルドカードを使用してホスト値を指定することもできます。 SQL パターン文字「%」および「_」を使用でき、クエリで LIKE 演算子を使用する場合と同じ意味になります (正規表現演算子は使用できません)。
SQL パターン文字は、ホスト名と IP アドレスの両方に使用できます。たとえば、%wisc.edu は wisc.edu ドメイン内の任意のホストに一致し、%.edu は College of Education の任意のホストに一致します。同様に、192.168.% は 192.168 のすべてと一致します。
クラス B サブネット上のホスト、および 192.168.3.% は 192.168.3 上のすべてに一致します。
クラス C サブネット上のホスト。
% 値はすべてのホストに一致し、ユーザーがどこからでも接続できるようにするために使用できます。空白のホスト値は % に相当します。 (例外: DB テーブルで、空白の Host 値は「ホスト テーブルをさらにチェックする」ことを意味します。このプロセスは「クエリ アクセスの検証」で紹介されています。)
MySQL より
3.23 以降では、ネットワーク アドレスに使用されるネットマスクを指定して IP アドレスを指定することもできます。たとえば、192.168.128.0/17 は 17 ビットのネットワーク アドレスを指定し、IP アドレスが最初の 17 桁であるホストと一致します。 192.168128の。
ユーザー
ユーザー名はテキストまたは空白である必要があります。空白の値は任意のユーザーと一致します。ユーザー値としての % は空白を意味するのではなく、リテラルの % 名と一致しますが、これはおそらくあなたが望むものではありません。
受信接続がユーザー テーブルを通じて認証され、一致するレコードに空のユーザー値が含まれている場合、クライアントは匿名ユーザーとみなされます。
PassWord
パスワード値は空でも空以外でもかまいません。ワイルドカードは使用できません。空のパスワードは、どのパスワードでも一致するという意味ではなく、ユーザーがパスワードを指定する必要がないことを意味します。
パスワードはリテラルテキストではなく、暗号化された値として保存されます。 「パスワード」列に文字通りのパスワードを保存すると、ユーザーは接続できなくなります。 GRANT ステートメントと mysqladmin
パスワード コマンドはパスワードを自動的に暗号化しますが、INSERT、REPLACE、UPDATE、SET などのコマンドを使用する場合は、
PASSWORD などのコマンドの場合は、単に「new_password」ではなく、必ず PASSWORD("new_password") を使用してパスワードを指定してください。
Db
columns_priv テーブルと tables_priv テーブルでは、Db 値は実際のデータベース名 (文字通り) である必要があり、パターンと空白は許可されません。 db および host では、Db 値を文字通り指定することも、SQL パターン文字「%」または「_」を使用してワイルドカードを指定することもできます。 「%」または空白は任意のデータベースと一致します。
Table_name、Column_name
これらの列の値は、リテラルのテーブル名または列名である必要があり、パターンと空白は許可されません。
一部の範囲列はサーバーによって大文字と小文字が区別されると見なされますが、残りは区別されません。これらの原則を以下の表にまとめます。特に、クエリ内のテーブル名の大文字と小文字の区別は、サーバーが実行されているホストのファイル システムによって異なりますが、Table_name の値は常に大文字と小文字が区別されるものとして扱われることに注意してください (UNIX では大文字と小文字が区別されますが、Windows では大文字と小文字が区別されません)。 )。
表 3
付与テーブル範囲列の大文字と小文字の区別
列
ホスト
ユーザー
パスワード
Db
テーブル名
列名
大文字と小文字の区別
いいえ
はい
はい
はい
はい
いいえ
2.2.2
クエリ アクセスの検証
クエリを発行するたびに、サーバーはクエリを実行するための十分な権限があるかどうかを確認し、適切なアクセス権があると判断するか、すべてのテーブルを検索したと判断するまで、user、db、tables_priv、columns_priv の順にチェックします。発見された。具体的には:
サーバーは、接続を開始したテーブルと一致するレコードがユーザー テーブルにあるかどうかを確認して、どのようなグローバル権限を持っているかを確認します。クエリに必要な情報があり、それらがクエリに十分であれば、サーバーはクエリを実行します。
グローバル権限が十分でない場合、サーバーはデータベーステーブルを検索し、レコード内の権限をグローバル権限に追加します。結果がクエリに対して十分である場合、サーバーはクエリを実行します。
グローバル レベルとデータベース レベルの権限を組み合わせた権限が不十分な場合、サーバーは引き続き最初に tables_priv テーブルを検索し、次に columns_priv テーブルを検索します。
すべてのテーブルをチェックした後も権限がない場合、サーバーはクエリの実行を拒否します。
ブール用語では、認可テーブルの権限はサーバーによって次のように使用されます:
user OR
tables_priv または
columns_priv
前の説明ではなぜ 4 つの認可テーブルしか参照していないのかと疑問に思われるかもしれませんが、実際には 5 つあります。実際、サーバーは次のようにアクセス許可をチェックします:
user
OR (データベース AND ホスト) OR tables_priv OR
columns_priv
最初の簡単な式は、ホスト テーブルが GRANT および REVOKE ステートメントの影響を受けないためです。ユーザー権限の管理に常に GRANT と REVOKE を使用する場合は、ホスト テーブルについて考える必要はありません。しかし、それがどのように機能するかを知っておく必要があります:
サーバーはデータベース レベルの権限をチェックするときに、クライアントの db テーブルを検索します。 [ホスト] 列が空の場合は、「ホスト テーブルをチェックしてデータベースにアクセスできるホストを確認する」ことを意味します。
サーバーはホストテーブル内で、DB テーブルのレコードと同じ DB 列値を探します。クライアントのホストと一致するホスト レコードがない場合、データベース レベルのアクセス許可は付与されません。これらのレコードのいずれかに、接続されたクライアントのホストと一致するホスト列の値がある場合、db テーブル レコードとホスト テーブル レコードが結合されて、クライアントのデータベース レベルのアクセス許可が生成されます。
ただし、アクセス許可は論理 AND で結合されます。これは、特定のアクセス許可が両方のテーブルに存在しない限り、クライアントはそのアクセス許可を持たないことを意味します。このようにして、db テーブルで基本的な権限セットを付与し、ホスト テーブルを使用して特定のホストに対してそれらの権限を選択的に無効にすることができます。たとえば、ドメイン内のすべてのホストからのデータベース アクセスを許可し、安全性の低いゾーンにあるホストのデータベース アクセス許可をオフにすることができます。
上記の説明では、特にサーバーが発行するすべてのクエリに対して権限チェックを実行すると考えると、アクセス チェックがかなり複雑なプロセスのように聞こえるかもしれませんが、サーバーは実際には承認テーブルをチェックしないため、このプロセスは非常に高速です。代わりに、起動時にテーブルの内容をメモリに読み取り、クエリがメモリ内のコピーを使用していることを確認します。これにより、アクセスチェック操作のパフォーマンスが大幅に向上します。しかし、非常に明らかな副作用があります。権限テーブルの内容を直接変更すると、サーバーは権限の変更を認識できません。
たとえば、INSERT ステートメントを使用してユーザー テーブルに新しいレコードを追加して新しいユーザーを追加すると、レコード内で指定されたユーザーはサーバーに接続できなくなります。これは、新しい管理者 (場合によっては経験豊富なベテラン) にとって非常に混乱を招くものでしたが、当時の解決策は単純でした。認可テーブルの内容を変更した後にサーバーにその内容を再ロードするよう指示し、FLUSH を送信するだけでした。
PRIVILEGES または mysqladmin を実行する
flash-privileges (または、flush-privilege をサポートしていない古いバージョンをお使いの場合は、mysqladmin を使用してください)
リロードします。 )。
2.2.3
範囲列の一致順序
MySQL サーバーは、認可テーブル内のレコードを特定の方法でソートし、レコードを順番に参照して受信接続を一致させます。最初に見つかった一致によって、どのレコードが使用されるかが決まります。 MySQL、特にユーザーテーブルで使用されるソート順序を理解することが重要です。
サーバーがユーザーテーブルの内容を読み取るとき、ホスト列とユーザー列の値に従ってレコードを並べ替えます。ホスト値が決定的な役割を果たします(同じホスト値がまとめて配置されます)。ユーザー値に従ってソートされます)。ただし、ソートはアロディックな順序付け (単語による順序付け) ではなく、部分的にのみ行われます。覚えておくべきことは、文字通りの単語がパターンよりも優先されるということです。これは、client.your.net からサーバーに接続しており、Host に client.your.net と %.your.net という 2 つの値がある場合、最初の値が最初に選択されることを意味します。同様に、%.your.net は %.net よりも優先され、次に % が優先されます。 IP アドレスの照合についても同様です。
一言で言えば、優先順位がより具体的になるということです。例については、この記事の付録を参照してください。
2.3
認可テーブルのリスクを回避する
このセッションでは、認可時のいくつかの予防策と、不明な値の選択によって引き起こされるリスクについて紹介します。一般に、スーパーユーザー権限の付与は非常に「ケチ」にする必要があります。つまり、ユーザー テーブルのエントリで権限を有効にせず、他の権限テーブルを使用して、データベース、テーブル、または列に対するユーザー権限を制限する必要があります。ユーザー テーブルの権限により、サーバーの操作に影響を与える任意のデータベース内の任意のテーブルへのアクセスが許可されます。
mysql データベースにアクセス許可を与えないでください。認可テーブルを含むデータベースに対する権限を持つユーザーは、テーブルを変更して他のデータベースに対する権限を取得できます。ユーザーに mysql データベース テーブルの変更を許可する権限を付与すると、ユーザーにグローバル GRANT 権限も効果的に付与されます。ユーザーがテーブルを直接変更できる場合、これは想像できるあらゆる GRANT ステートメントを発行できることと同じです。
FILE 権限は特に危険です。簡単に許可しないでください。 FILE 権限を持つユーザーが実行できることは次のとおりです:
CREATE
TABLE etc_passwd (pwd_entry TEXT);
LOAD DATA INFILE "/etc/passwd" に
TABLE etc_passwd;
SELECT * FROM
etc_passwd;
これらのステートメントを発行すると、ユーザーはすでにパスワード ファイルの内容を取得しています。実際、サーバー上の一般に読み取り可能なファイルの内容には、FILE 権限を持つユーザーがネットワーク経由でアクセスできます。
FILE 権限は、十分に制限的なファイル権限が設定されていないシステム上のデータベースを侵害するために悪用される可能性もあります。このため、サーバーのみが読み取りできるようにデータ ディレクトリを設定する必要があります。データベース テーブルに対応するファイルが、ユーザーのサーバー アカウントを持つユーザーだけでなく、誰でも読み取り可能な場合は、FILE 権限を持つユーザーもネットワーク経由で接続してファイルを読み取ることができます。このプロセスを以下に示します。
LONGBLOB 列を含むテーブルを作成します。
ユーザーテスト;
CREATE TABLE tmp (b
LONGBLOB);
このテーブルを使用して、盗むデータベース テーブルに対応する各ファイルの内容を読み取り、テーブルの内容を独自のデータベース内のファイルに書き込みます:
LOAD
データファイル "./other_db/x.frm" をテーブル tmp に挿入します
"" 行でエスケープされたフィールド
TERMINATED BY "";
SELECT * FROM tmp INTO OUTFILE "y.frm"
フィールド
「」でエスケープされました 「」で終了する行;
tmpから削除;
データINFILEをロード
"./other_db/x.ISD" INTO TABLE tmp
フィールドが "" 行でエスケープされ終了しました
BY "";
SELECT * FROM tmp INTO OUTFILE "y.ISD"
フィールドは "" によってエスケープされています
"" で終わる行;
tmp から削除;
データファイルをロード
"./other_db/x.ISM" INTO TABLE tmp
フィールドが "" 行でエスケープされ終了しました
BY "";
SELECT * FROM tmp INTO OUTFILE
「y.ISM」
これで、other_db.x の内容を含む新しいテーブル y が作成され、それに完全にアクセスできるようになりました。
他の人が同じように攻撃するのを防ぐため、「パート 1」によると
「内部セキュリティ - データ ディレクトリの保護」の手順に従ってデータ ディレクトリにアクセス許可を設定することもできます。また、サーバーの起動時に --skip-show-database オプションを使用して、ユーザーがアクセスしていないデータベースにアクセスできるように制限することもできます。アクセス権限を表示します。
データベースとショー
テーブル。これにより、ユーザーがアクセスできないデータベースやテーブルに関する情報を見つけることができなくなります。
ALTER 権限は意図しない方法で使用される可能性があります。 user1 には table1 にはアクセスできるが、table2 にはアクセスできないようにしたいとします。 ALTER 権限を持つユーザーは ALTER を使用できます
TABLE は、列を変更するために table2 の名前を table1 に変更します。
GRANT 権限に注意してください。異なる権限を持つ 2 人のユーザーが両方とも GRANT 権限を持っている場合、互いの権限を強化できます。
上記は MySQL セキュリティ ガイド (2) (再版) の内容です。その他の関連記事については、PHP 中国語 Web サイト (www.php.cn) に注目してください。