ストアドプログラムとビューは使用する前に定義され、参照されるときに、その権限を決定するセキュリティーのコンテキスト内で実行します。これらの権限は、その DEFINER
属性と、存在する場合はその SQL SECURITY
特性で制御されます。
すべてのストアドプログラム (プロシージャー、関数、トリガー、およびイベント) とビューには、MySQL アカウントを指名する DEFINER
属性を含めることができます。DEFINER
属性をストアドプログラムまたはビュー定義から省略した場合、デフォルトのアカウントは、オブジェクトを作成するユーザーになります。
さらに、ストアドルーチン (プロシージャーおよび関数) とビューには、値が DEFINER
または INVOKER
である SQL SECURITY
特性があり、オブジェクトが定義側のコンテキストで実行するか、呼び出し元のコンテキストで実行するかを指定できます。SQL SECURITY
特性を省略した場合、デフォルトは定義側のコンテキストになります。
トリガーとイベントには、SQL SECURITY
特性がなく、常に定義側のコンテキストで実行します。サーバーが必要に応じて自動的にこれらのオブジェクトを呼び出すので、呼び出し元ユーザーは存在しません。
定義側と呼び出し元のセキュリティーのコンテキストは次のように異なります。
定義側のセキュリティーコンテキストで実行するストアドプログラムまたはビューは、
DEFINER
属性で指名されたアカウントの権限で実行します。これらの権限は、呼び出し元ユーザーの権限とは完全に異なる場合があります。呼び出し元は、オブジェクトを参照するために適切な権限 (たとえば、ストアドプロシージャーを呼び出すためのEXECUTE
や、ビューから選択するためのSELECT
) が必要ですが、オブジェクトが実行すると、呼び出し元の権限は無視され、DEFINER
アカウント権限だけが重要になります。このアカウントの権限が低い場合、オブジェクトが実行できる操作は、それに応じて制限されます。DEFINER
アカウントに高い権限が与えられている場合 (root
アカウントなど)、呼び出し元のユーザーにかかわらず、オブジェクトは強力な操作を実行できます。呼び出し元のセキュリティーコンテキストで実行するストアドルーチンまたはビューは、呼び出し元が権限を持つ操作だけを実行できます。
DEFINER
属性は指定できますが、呼び出し元のコンテキストで実行するオブジェクトに対して効果はありません。
次のストアドプロシージャーを検討してください。
CREATE DEFINER = 'admin'@'localhost' PROCEDURE p1()
SQL SECURITY DEFINER
BEGIN
UPDATE t1 SET counter = counter + 1;
END;
p1
に対する EXECUTE
権限を持つどのユーザーでも、CALL
ステートメントを使用してこれを呼び出すことができます。ただし、p1
が実行するときには、DEFINER
のセキュリティーコンテキストで実行するので、DEFINER
属性で指名されたアカウントである 'admin'@'localhost'
の権限で実行します。このアカウントは、p1
の EXECUTE
権限のほかに、テーブル t1
の UPDATE
権限が必要です。それ以外の場合、プロシージャーは失敗します。
続いて次のストアドプロシージャーを検討してください。これは p1
と同じですが、その SQL SECURITY
特性が INVOKER
である点が異なります。
CREATE DEFINER = 'admin'@'localhost' PROCEDURE p2()
SQL SECURITY INVOKER
BEGIN
UPDATE t1 SET counter = counter + 1;
END;
p2
は p1
と異なり、INVOKER
のセキュリティーコンテキストで実行します。DEFINER
属性は無関係であり、p2
は呼び出し元ユーザーの権限で実行します。呼び出し元に p2
に対する EXECUTE
権限、またはテーブル t1
に対する UPDATE
権限が不足している場合、p2
は失敗します。
MySQL は、次のルールを使用して、ユーザーがオブジェクトの DEFINER
属性で指定できるアカウントを制御します。
SUPER
権限がある場合にかぎり、自身のアカウント以外のDEFINER
値を指定できます。SUPER
権限がない場合、唯一の正当なユーザー値は、文字どおり指定するか、CURRENT_USER
を使用して指定した自身のアカウントです。定義者をほかのアカウントに設定することはできません。
ストアドプログラムおよびビューの作成と使用に関して考えられるリスクを最小限に抑えるため、次のガイドラインに従ってください。
可能な場合は、ストアドルーチンまたはビューに対して、オブジェクト定義の
SQL SECURITY INVOKER
を使用して、オブジェクトが実行する操作に適したアクセス許可を持つユーザーだけが使用できるようにします。SUPER
権限を持つアカウントの使用中に、定義側のコンテキストのストアドプログラムまたはビューを作成する場合は、オブジェクトが実行する操作に必要な権限だけを所有しているアカウントを指名する明示的なDEFINER
属性を指定します。高い権限を持つDEFINER
アカウントは、絶対に必要な場合にのみ指定してください。管理者は、
SUPER
権限をユーザーに与えなければ、高い権限を持つDEFINER
アカウントをユーザーが指定できないようにできます。-
定義側のコンテキストのオブジェクトを作成するときには、呼び出し元ユーザーに権限のないデータに定義側がアクセスできる場合があります。権限のないユーザーに特定の権限を与えなければ、これらのオブジェクトへの参照を防止できる場合があります。
ストアドプロシージャーまたはストアドファンクションに対する
EXECUTE
権限を持たないユーザーは、これを参照できません。ビューに対する適切な権限 (ビューから選択するための
SELECT
、ビューに挿入するためのINSERT
など) を持っていないユーザーは、ビューを参照できません。
ただし、トリガーに対するこのような制御は存在しません。ユーザーが直接トリガーを参照することはないからです。トリガーは常に、
DEFINER
コンテキストで実行し、特別な権限を持たないユーザーによる通常のテーブルアクセスを含め、トリガーが関連付けられているテーブルへのアクセスがあるとアクティブ化されます。DEFINER
アカウントに高い権限が与えられている場合、トリガーは、慎重を要する操作または危険な操作を実行できます。トリガーの作成に必要なSUPER
およびTRIGGER
権限が、作成したユーザーのアカウントから削除された場合にも、このことは引き続き当てはまります。管理者は、この権限の組み合わせをユーザーに認める場合、特に注意する必要があります。