この章では、トラステッド・ストアド・プログラム・ユニットを使用してシステム・セキュリティを強化する方法について説明します。この章の内容は、次のとおりです。
Oracle Databaseストアド・プロシージャ、ファンクションおよびパッケージは、コンパイルされた形式でデータベースに格納されているPL/SQL文のセットです。ファンクションとプロシージャの唯一の違いは、ファンクションは値を戻すのに対して、プロシージャは値を戻さないことです。トラステッド・ストアド・プログラム・ユニットは、Oracle Databaseの他のストアド・プログラム・ユニットと同様で、基礎となるロジックは同じです。
パッケージは、使用するカーソルおよび変数とともにユニットとして格納されるプロシージャとファンクションのセットです。 パッケージは、パッケージ仕様部とパッケージ本体という2つの部分で構成されています。パッケージ仕様部では、パッケージに含まれるパブリック・プロシージャ、ファンクションおよび変数の外部定義を宣言します。パッケージ本体には、プロシージャとファンクションの実際のテキストと、プライベートなプロシージャおよび変数が含まれています。
トラステッド・ストアド・プログラム・ユニットは、1つ以上のOracle Label Security権限を付与されたストアド・プロシージャ、ファンクションまたはパッケージです。通常、トラステッド・ストアド・プログラム・ユニットは、ユーザーが権限を付与されている操作を制御された方法で実行したり、複数のラベルのデータを更新できるようにするために使用されます。これは、ユーザーに対して認可の範囲を超えるデータへのアクセスを許可する場合に最適なアプローチです。
トラステッド・ストアド・プログラム・ユニットは、権限の使用に対するファイングレイン・コントロールを提供します。多数のユーザーに潜在的に権限を付与できますが、アプリケーションについて設定したセキュリティ・ポリシーに違反する可能性があるため、権限の付与には細心の注意を払う必要があります。ユーザーに権限を割り当てるのではなく、権限を必要とするアプリケーション操作を識別し、それをトラステッド・プログラム・ユニットとして実装できます。このようなストアド・プログラム・ユニットに権限を付与すると、実際にはユーザーが必要とするOracle Label Security権限を制限することになります。このアプローチは、最小限の権限の原理を採用しています。
たとえば、ラベルCONFIDENTIALを持つユーザーがSENSITIVE行へのデータの挿入を必要とする場合は、ユーザーがアクセスするトラステッド・ストアド・プログラムにWRITEUP権限を付与できます。これにより、ユーザーはトラステッド・ストアド・プログラムを使用して、CONFIDENTIALレベルでタスクを実行できます。
すべてのアクションは、ユーザーにかわってトラステッド・プログラム・ユニットにより実行されます。そのため、セキュリティ・ポリシーをモジュールに効率的にカプセル化し、それが有効かどうかを検証できます。
トラステッド・ストアド・プログラム・ユニットは、独自の権限とコール元のラベルを使用して実行されます。このようにして、ユーザーのラベルで制約されている行セットに対して、権限が付与されている操作を実行できます。
Oracle Databaseシステムおよびオブジェクト権限は、ロールにバンドルすることを意図しています。ユーザーには、必要に応じてロール権限が付与されます。これに対して、Oracle Label Security権限の割当て対象となるのは、ユーザーまたはストアド・プログラム・ユニットのみです。この種のトラステッド・ストアド・プログラム・ユニットは、Oracle Label Security権限の使用を制御するという点で、ロールよりも管理しやすいメカニズムを提供します。
READ権限を持つトラステッド・ストアド・プログラム・ユニットは、データベース内で保護されていないすべてのデータと、このポリシーにより保護されているすべてのデータを読み取ることができます。たとえば、購買予測レポートの作成を担当するユーザーを考えます。このユーザーは、すべての発注金額の集計操作を実行する必要があります。これは、そのユーザーのラベルで個々の発注書へのアクセスが認可されているかどうかには関係ありません。この例で集計プロシージャを作成する構文は、次のとおりです。
CREATE FUNCTION sum_purchases RETURN NUMBER IS psum NUMBER; BEGIN SELECT SUM(amount) INTO psum FROM purchase_orders; RETURN psum; END sum_purchases;
これにより、プログラム・ユニットは、エンド・ユーザーが収集できない情報を収集し、集計により使用可能にできます。
SUM_PURCHASESを実行するには、ユーザーにこのプロシージャに対する標準Oracle Database EXECUTEオブジェクト権限が付与されている必要があります。
ストアド・プログラム・ユニットに権限を付与するには、policy_DBAロールと、SA_USER_ADMINパッケージに対するEXECUTE許可が必要です。Oracle Label Security権限を管理するには、SA_USER_ADMINパッケージを使用する方法と、Oracle Enterprise Managerを使用する方法があります。
SA_USER_ADMIN.SET_PROG_PRIVSプロシージャを使用して、プログラム・ユニットについてポリシー固有の権限を設定します。privilegesパラメータがNULLの場合は、ポリシーに対するプログラム・ユニットの権限が削除されます。
構文:
PROCEDURE SET_PROG_PRIVS ( policy_name IN VARCHAR2, schema_name IN VARCHAR2, program_unit_name IN VARCHAR2, privileges IN VARCHAR2);
パラメータ | 指定 |
---|---|
policy_name | 既存のポリシーの名前です。 |
program_unit_name | 権限を付与するプログラム・ユニットを指定します。 |
privileges | ポリシー固有の権限をカンマで区切って文字列として指定します。 |
たとえば、SUM_PURCHASESファンクションにREAD権限を付与するには、次のように入力します(「トラステッド・ストアド・プログラム・ユニットの例」を参照)。
EXECUTE sa_user_admin.set_prog_privs ( 'HR','myschema','sum_purchases','READ');
SUM_PURCHASESプロシージャがコールされると、現行ユーザーのOracle Label Security権限に加えてREAD権限で実行されます。このテクニックを使用すると、ユーザーには、個々の従業員の給与を知らせずに、会社全体の給与の合計値を検索するように許可できます。
警告: トラステッド・ストアド・プログラム・ユニットを作成する場合は、Oracle Label Security管理者に、付与された権限を慎重に検討して評価するように指示してください。たとえば、トラステッド・パッケージ内のプロシージャが、権限を付与されているデータベース操作を実行し、パッケージのパブリック変数の結果またはステータス情報を書き込まないようにします。これにより、サイトのOracle Label Securityポリシーに違反が発生しないことが確実になります。 |
この項には、次の項目が含まれます。
トラステッド・ストアド・プログラム・ユニットの作成方法は、標準的なプロシージャ、ファンクションまたはパッケージを作成する場合と同じで、CREATE PROCEDURE、CREATE FUNCTIONまたはCREATE PACKAGEおよびCREATE PACKAGE BODYの各文を使用します。プログラム・ユニットは、Oracle Label Security権限を付与するとトラステッド・プログラム・ユニットになります。
関連項目: 『Oracle Database SQL言語クイック・リファレンス』 |
開発者がストアド・プログラム・ユニットを作成すると、Oracle Label Security管理者はコードが正しいかどうかを検証してから、ストアド・プログラム・ユニットに必要な権限を付与できます。トラステッド・ストアド・プログラム・ユニットが再作成または置換されると、その権限は削除されます。Oracle Label Security管理者はコードを再検証し、権限を再び付与する必要があります。
トラステッド・ストアド・プログラム・ユニットの再コンパイルを自動的に行うか手動で(ALTER PROCEDUREを使用して)行うかは、Oracle Label Security権限には影響しません。ただし、再コンパイル後はプログラム・ユニットに対するEXECUTE権限を再び付与する必要があります。
Oracle Label Security権限は、トラステッド・ストアド・プログラム・ユニットに対してCREATE OR REPLACE操作を実行すると取り消されます。これにより、プロシージャでOracle Label Security権限が誤用される可能性が限定されます。Oracle Label Security権限が取り消されても、プロシージャ、ファンクションまたはパッケージは引き続き実行できることに注意してください。
プロシージャ、ファンクションまたはパッケージを再作成する場合は、そのテキストを慎重に検討する必要があります。再作成後のプログラム・ユニットがサイトのOracle Label Securityポリシーに違反しないことが確実であれば、必要な権限を再び付与できます。
トラステッド・ストアド・プログラム・ユニットを頻繁に置換する必要のある開発環境(本番システムの最初の数か月など)では、必要に応じて適切なOracle Label Security権限を付与できるようにスクリプトを作成することをお薦めします。
Oracle Label Securityでは、(表およびスキーマへのアクセスに関する)プロシージャ・コールのすべての標準Oracle Databaseコントロールはまだ有効です。Oracle Label Securityは、行へのアクセスを制御することで、これらのセキュリティ・メカニズムを補完します。トラステッド・ストアド・プログラム・ユニットの実行時に有効なポリシー権限は、コール側ユーザーの権限とプログラム・ユニットの権限との共用部分です。トラステッド・ストアド・プログラム・ユニットが別のトラステッド・プログラム・ユニットまたは非トラステッド・プログラム・ユニットをコールすると、コールされたプログラム・ユニットはコール側のプログラム・ユニットと同じ権限で実行されます。
非トラステッド・ストアド・プログラム・ユニットとトラステッド・ストアド・プログラム・ユニットが連なって実行される場合、最初のトラステッド・プログラム・ユニットによって、それ以降の順序でコールされるプログラム・ユニット全体の権限が決まります。次の順序を考えてみます。
プロシージャBは順序内の最初のトラステッド・プロシージャのため、プロシージャB、CおよびDはすべてWRITEUP権限で実行されます。順序が終了すると、プロシージャBに関する権限は後続のプロシージャには無効になります。
SA_UTLパッケージには、PL/SQLプログラムで使用できるように複数のファンクションが用意されています。これらのファンクションは、セッションのセキュリティ属性の現在の値に関する情報を、数値のラベル値書式で戻します。これらのファンクションは、非トラステッド・プログラム・ユニットにも使用できますが、主としてトラステッド・ストアド・プログラム・ユニット用です。
これらはパブリック・ファンクションであり、policy_DBAロールがなくても使用できることに注意してください。また、各ファンクションには、同じラベルを文字列書式で戻すパラレルのSA_SESSIONファンクションがあります。
SA_UTLには、セッション・ラベルと行ラベルを表示するための次のプロシージャが用意されています。
このプロシージャは、現行セッション・ラベルを戻します。入力パラメータとしてポリシー名を取り、NUMBER値を戻します。
SA_UTL.NUMERIC_LABEL (policy_name) RETURN NUMBER;
SA_UTL
には、ポリシーのラベル付きデータに対する現行セッションのユーザー権限をチェックするための次のファンクションが用意されています。
このファンクションを使用して、ユーザーがポリシーで保護されている表の行を読み取ることができるかどうかをチェックします。ユーザーが表の行を読み取ることができる場合は1が戻されます。ユーザーが表の行を読み取ることができない場合は0(ゼロ)が戻されます。入力値はポリシー名と行のデータ・ラベルです。
FUNCTION CHECK_READ ( policy_name IN VARCHAR2, label IN NUMBER) RETURN NUMBER;
注意: 表のデータを読み取るには、ユーザーにその表に対する読取り権限が必要です。 |
このファンクションを使用して、ユーザーがポリシーで保護されている表の行データの挿入、更新または削除を実行できるかどうかをチェックします。ユーザーが表の行に書き込むことができる場合は1が戻されます。ユーザーが表の行に書き込むことができない場合は0(ゼロ)が戻されます。入力値はポリシー名と行のデータ・ラベルです。
FUNCTION CHECK_WRITE ( policy_name IN VARCHAR2, label IN NUMBER) RETURN NUMBER;
注意: 表にデータを書き込むには、ユーザーにその表に対する更新権限が必要です。 |
このファンクションを使用して、ユーザーがポリシーで保護されている表の行に対するデータ・ラベルを変更できるかどうかをチェックします。ユーザーがデータ・ラベルを変更できる場合は1が戻されます。ユーザーがデータ・ラベルを変更できない場合は0(ゼロ)が戻されます。入力値は、ポリシー名、現在のデータ・ラベルおよび新しいデータ・ラベルです。
FUNCTION CHECK_LABEL_CHANGE ( policy_name IN VARCHAR2, current_label IN NUMBER, new_label IN NUMBER) RETURN NUMBER;
注意: 表にデータを書き込むには、ユーザーにその表に対する更新権限が必要です。 |
これらのプロシージャは、入力値として、文字列ではなく数値ラベルを使用します。これと同じファンクションを文字列書式で実行するSA_SESSIONプロシージャを使用できます。
このプロシージャを使用して、現行データベース・セッションのラベルを設定します。セッションの書込みラベルと行ラベルは、書込みアクセスが認可されているラベルの区分とグループのサブセットに設定されます。
PROCEDURE SET_LABEL (policy_name IN VARCHAR2, label IN NUMBER);
パラメータ | 指定 |
---|---|
policy_name | 既存のポリシーの名前 |
label | セッション・ラベルとして設定するラベル |
最大の下限と最小の上限を戻すファンクションを使用できます。
このファンクションは、2つのラベルの引数の最大の下限であるラベルを戻します。
構文:
FUNCTION GREATEST_LBOUND (label1 IN NUMBER, label2 IN NUMBER) RETURN NUMBER;