テスト用に作成したAPEXアプリケーションは、意図的にSQLインジェクションに脆弱にしています。仮想プライベート・データベースを構成することにより、APEXアプリケーションへ変更を変更せずに(認証スキームは変更します)SQLインジェクションを防いでみます。
認証スキームの変更
仮想プライベート・データベースによる表HR.EMPの保護を実装するにあたり、作成済みのAPEXアプリケーションを従業員によって認証するように変更します。
最初に認証に使用する表AUTH_USERSを表HR.USERSより作成します。
APEXのSQLワークショップのSQLコマンドより実行します。
テスト用アプリケーションの共有コンポーネントの認証スキームを開き、作成を実行します。
スキームの作成として、ギャラリからの事前構成済スキームに基づくを選択し、次に進みます。
名前を従業員による認証とし、スキーム・タイプとしてカスタムを選択します。ソースのPL/SQLコードに、下記のファンクションauth_employees_onlyを記述します。
認証ファンクション名にauth_employees_onlyを指定します。ユーザー名が従業員名に一致しているとサインインに成功します。パスワードの検証は行いません。従業員名は大文字なので、ユーザー名も大文字で入力する必要があります。
認証スキームの作成をクリックします。
作成された認証スキーム従業員による認証は、作成後よりカレント・スキームになります。
アプリケーションを実行し、サインインの確認を行います。ユーザーAPEXDEVでサインインしたままの場合は、一旦サインアウトします。
ユーザー名として大文字でSCOTTと入力し、サインインをクリックします。パスワードは検証に使用されません。
以上で認証スキームは作成は完了です。
ユーザーVPDADMINの作成
仮想プライベート・データベースを構成するユーザーVPDADMINを作成します。データベース・アクションよりデータベース・ユーザーを開きます。ユーザーの作成をクリックします。
ユーザー名としてVPDADMINを指定します。パスワードを設定し、WebアクセスをONに設定します。ユーザーの作成をクリックします。
ユーザーVPDADMINが作成されます。WebアクセスをONとしているため、データベース・アクションにVPDADMINとして接続することができます。
ユーザーVPDADMINが仮想プライベート・データベースを構成するために必要な権限を割り当てます。データベース・アクションのSQLを開き、以下を実行します。
仮想プライベート・データベースの構成
仮想プライベート・データベースの構成作業を行います。データベース・アクションにユーザーVPDADMINにてサインインします。開発のSQLを開きます。
最初にアプリケーション・コンテキストEMP_DEPT_CTXを作成します。このアプリケーション・コンテキストを操作するパッケージはEMP_DEPT_CTX_PKGとします。
作成されたアプリケーション・コンテキストはビューDBA_CONTEXTより参照できます。(ビューの参照権限が必要です。)
続いてパッケージEMP_DEPT_CTX_PKGとそのパッケージ本体を作成します。次のスクリプトを実行します。アプリケーション・コンテキストにはサインインしたユーザーの従業員番号empnoと部門番号deptnoが保持されます。作成されたパッケージはユーザーAPEXDEVから実行できるよう、実行権限を与えます。
仮想プライベート・データベースのポリシーを作成します。
最初に作成するポリシーは、表EMPの検索範囲をサインインしたユーザーと同じ部門に制限するポリシーemp_in_same_deptnoです。
検索条件を生成するファンクションpred_emp_in_same_deptnoを作成します。
続けてポリシーemp_in_same_deptnoを作成します。プロシージャDBMS_RLS.ADD_POLICYを呼び出します。
もうひとつ作成するポリシーは、自分自身がマネージャである従業員の列SALとCOMMのみ参照できるように制限するポリシーemp_is_mgrです。
条件を生成するファンクションはpred_emp_is_mgrです。ファンクションを作成した後にポリシーemp_is_mgrを作成します。
以上で表HR.EMPを保護するための設定が完了しました。
作成された仮想プライベート・データベースのポリシーはビューALL_POLICIESより参照できます。
APEXアプリケーションの変更
APEXアプリケーションにアプリケーション・コンテキストを操作する設定を追加します。アプリケーション定義属性のセキュティのデータベース・セッションの初期化PL/SQLコードとして
vpdadmin.emp_dept_ctx_pkg.init;
PL/SQLコードのクリーンアップとして
vpdadmin.emp_dept_ctx_pkg.clear;
を指定します。
以上でアプリケーションの修正も完了です。
動作確認
アプリケーションにユーザーSCOTTでサインインし、従業員名として以下を指定してレポートを表示させます。
SCOTT' or '1' = '1
レポートのSQL問合せには変更がなくSQLインジェクションに脆弱なままですが、レポートに表示される従業員はSCOTTと同じ部門の従業員に限定されています。
続いて、以下を指定してレポートを表示します。
SCOTT' UNION SELECT EMPNO, ENAME || ' - ' || SAL || ' - ' || COMM ENAME, JOB, MGR, HIREDATE, DEPTNO FROM HR.EMP WHERE '1'='1
Enameに列SALの値が表示されていますが、SCOTTがマネージャーである従業員ADAMSに限定されています。
ポリシーの削除
後続の作業に影響があるため、作成した仮想プライベート・データベースのポリシーを削除します。