この章では、最適なセキュリティのためにデータベースとPL/SQLを設定する方法について説明します。この章の内容は、次のとおりです。
mod_plsqlは、データベース・アカウントが権限を有するプロシージャへのアクセスに使用できるPL/SQLゲートウェイです。これにはPUBLICに付与されているすべてのパッケージへのアクセス権も含まれているため、PL/SQLアプリケーション側で、権限のないパッケージまたはプロシージャへのアクセスにmod_plsqlが使用されないようにする必要があります。デフォルトでは、mod_plsqlがアクセスできない対象は次のとおりです。
重要なスキーマ。SYS.*
など。
重要と認識されているが、PUBLICでアクセスできるパッケージ。OWA_*
、DBMS_*
およびUTL_*
パッケージなど。
URLに特殊文字を含むプロシージャ名。
mod_plsqlを使用して直接実行されないように、特定のパッケージへのアクセスを明示的に拒否するこのデフォルト・モデルは、適切に設計されたPL/SQLアプリケーションの大部分に対しては十分です。このレベルのセキュリティがPL/SQLアプリケーションには不十分である場合は、次の方法を1つ以上使用して、PL/SQLアプリケーションを確実に保護することをお薦めします。
mod_plsqlには、PlsqlRequestValidationFunction
というDADパラメータ・ディレクティブが用意されています。このディレクティブを使用すると、リクエストされたプロシージャのそれ以上の処理を許可または禁止できます。このディレクティブは、DADからの実行を禁止されたパッケージまたはプロシージャ・コールをブロックして、PL/SQLアプリケーションについて厳重なセキュリティを実装する場合に役立ちます。
このパラメータによって定義されるファンクションには、次のプロトタイプが必要です。
boolean function_name (procedure_name IN varchar2)
起動時には、引数procedure_name
に、リクエストで実行しようとしているプロシージャの名前が含まれます。
たとえば、ブラウザからコールできるすべてのPL/SQLアプリケーション・プロシージャがパッケージmypkg内にある場合、このファンクションの実装は例2-1に示すような単純なものになります。
例2-1 プロシージャをブロックするリクエスト検証ファンクションの実装
boolean my_validation_check (procedure_name varchar2) is begin if (upper(procedure_name) like upper('myschema.mypkg%')) then return TRUE; else return FALSE; end if; end;
ヒント:
|
mod_plsqlには、PlsqlExclusionList
というDAD設定パラメータが用意されています。このパラメータを使用すると、特定のパターンを持つプロシージャをブラウザURLから直接実行することを禁止できます。指定されるパターンには大/小文字の区別はなく、任意の文字の組合せが0回以上発生することを示すワイルドカード・パターンの*
を使用できます。ダイレクトURLからアクセスできないデフォルトのパターンは、sys.*
、dbms_*
、utl_*
、owa_util.*
、owa_*
、ctxsys.*、mdsys.*、htp.*
およびhtf.*
です。Oracle Application Server 10g リリース2(10.1.2)からは、ユーザーがPlsqlExclusionList
を使用して追加ルールを構成していても、デフォルトの組込み除外リストは引き続き有効です。以前のバージョンでは、PlsqlExclusionList
ディレクティブがDAD設定でオーバーライドされると、デフォルト設定は適用されませんでした。
mod_plsqlでは、このディレクティブで指定したパターンの他に、タブ、改行、一重引用符('
)、バックスラッシュ(\
)などの特殊文字を含むURLも却下されます。
このディレクティブは、1つ以上の除外されたパッケージに作成された可能性があるデータベース・シノニムからの保護を提供しません。シノニムが存在し、脆弱である場合は、そのシノニムを除外されるパターンのリストに明示的に追加する必要があります。
PlsqlExclusionList
パラメータの詳細は、『Oracle Fusion Middleware Oracle HTTP Server管理者ガイド』の「mod_plsql」を参照してください。
注意: PlsqlExclusionList ディレクティブを#NONE#に設定すると、すべての保護が無効になるため、アクティブなWebサイトには使用しないでください。 |
dads.conf
というmod_plsqlの構成ファイルに、PlsqlExclusionList
ディレクティブを設定できます。この設定ファイルは、次のディレクトリにあります。
(UNIX) INSTANCE_HOME
/config/OHS/ohs1/mod_plsql
(Windows) INSTANCE_HOME
\config\OHS\ohs1\mod_plsql
INSTANCE_HOME
は、Oracle HTTP Serverをインストールした場所です。
PUBLICに付与されるユーザー定義のPL/SQLプロシージャに対して最適なセキュリティを確保するには、例2-2に示すように、PlsqlExclusionList
ディレクティブを使用してユーザー設定をdads.conf
ファイルに指定します。
カスタム認証を使用するアプリケーションでは、AUTHORIZEプロシージャの実装で制限付きパッケージまたはプロシージャへのアクセスを拒否できます。
アプリケーション・オブジェクト(表およびプロシージャ)を含むスキーマを、mod_plsqlの実行対象であるスキーマと区別することが役に立つ場合があります。このようにすると、mod_plsqlがユーザーとして接続するとき、そのユーザーに付与されたAPI以外を経由して、表およびその他のデータベース・オブジェクトに直接アクセスすることを禁止できます。シノニムを使用すると、スキーマ接頭辞を付けなくてもプロシージャは実行可能になります。
SQLインジェクション攻撃は、悪質なユーザーがバックエンド・データベースに対して実行されているSQLコマンドを変更できる場合に発生します。変更内容には、追加のデータを読み取ること、失敗するはずの妥当性チェックを成功させること、レコードを書き込むこと、またはその他の方法でアプリケーションの円滑な実行に影響を与えることなどがあります。
多くのアプリケーションがデータベース上に構築されており、通常、ユーザー入力がデータベース問合せの一部として使用されています。アプリケーションのコーディングが慎重に行われていない場合、入力内容を注意深く構成することで、データベースに送信される問合せを変更できることがあります。
このようなSQLインジェクション攻撃を回避するには、ユーザーの入力によって作成される動的SQLを可能なかぎり使用しないようにします。
動的SQLにユーザー入力を使用する必要がある場合には、動的SQLで使用する前に、アプリケーション側で入力内容を適切にフィルタ処理する必要があります。たとえば、ユーザーが入力パラメータとして表の名前を入力する場合、基礎となるアプリケーション・コードで、このパラメータに使用できる値が有効な表の名前のみとなるようにする必要があります。
mod_plsqlでは、Oracle HTTP Serverから提供される認証レベルに加えて、様々な認証レベルを提供します。Oracle HTTP Serverはドキュメントや仮想パスなどを保護しますが、mod_plsqlはデータベースにログインしたり、PL/SQL Webアプリケーションを実行するユーザーを保護します。
表2-1に示すように、様々な認証モードを有効化できます。
表2-1 mod_plsqlで使用する認証モード
認証モード | アプローチ |
---|---|
Basic |
HTTPのBasic認証を使用して認証が実行されます。ほとんどのアプリケーションでは、Basic認証が使用されます。 |
グローバルOWA |
認証は、PL/SQL Web Toolkitパッケージを含むスキーマのowa_custom.authorizeプロシージャを使用して実行されます。 |
カスタムOWA |
認証は、ユーザーのスキーマ(owa_customize.authorize)にあるパッケージとプロシージャを使用して実行されます。それが見つからない場合は、PL/SQL Web Toolkitパッケージを含むスキーマのパッケージとプロシージャが使用されます。 |
パッケージ別 |
認証は、ユーザーのスキーマ(packageName.authorize)にあるパッケージとプロシージャを使用して実行されます。 |
シングル・サインオン |
認証は、Oracle Application Server Single Sign-Onを使用して実行されます。このモードを使用するのは、アプリケーションがOracleAS Single Sign-On Serverで動作する場合のみです。 |
モジュールmod_plsqlは、データベース・レベルでの認証をサポートしています。HTTP Basic認証が使用されますが、この方式を使用してデータベースへのログオンを試行することで資格証明が認証されます。認証は、次のどちらかのユーザー名とパスワードを使用して、ユーザーのデータベース・アカウントと比較検証されます。
DADに格納されているユーザー名とパスワード。エンド・ユーザーがログインする必要はありません。この方法は、公開情報を提供するWebページに便利です。
ユーザーがブラウザのHTTP Basic認証ダイアログ・ボックスを使用して入力するユーザー名とパスワード。ユーザーは、このダイアログ・ボックスにユーザー名とパスワードを入力する必要があります。
Oracle HTTP Serverでは、Basic認証モードの仕組みが異なります。ユーザー名およびパスワードはDADに格納する必要があります。Oracle HTTP Serverでは、ファイル・システム上のパスワード・ファイルに資格証明が格納されている、HTTP Basic認証を使用します。認証は、そのファイルに指定されているユーザーと比較検証されます。
Basic認証モード
mod_plsqlは、Basic認証をサポートしています。Oracle HTTP Serverでは、ユーザーの資格証明をファイル・システム上のパスワード・ファイルと照合して認証します。この機能は、mod_auth
というモジュールによって提供されます。
カスタム認証を使用すると、データベース・レベルではなくアプリケーション自体でユーザーを認証できます。認証は、ユーザー記述の認証ファンクションをコールすることで実行されます。
カスタム認証は、OWA_CUSTOMを使用して行われ、動的ユーザー名およびパスワード認証とは組み合せることができません。カスタム認証には、DAD設定ファイルに格納されている静的ユーザー名およびパスワードが必要です。mod_plsqlは、このDADユーザー名およびパスワードを使用してデータベースにログインします。mod_plsqlはログインすると、アプリケーション・レベルのPL/SQLフックをコールして、認証コントロールをアプリケーションに戻します。このコールバック・ファンクションは、アプリケーション開発者によって実装されます。コールバック・ファンクションの戻り値により、認証の成功または失敗が決まります。値TRUE
は成功を意味し、FALSE
は失敗を意味します。
必要なカスタム認証の種類に応じて、認証ファンクションは様々な場所に配置できます。
グローバルOWAの場合は、すべてのユーザーおよびプロシージャに対して同じ認証ファンクションをコールできます。
カスタムOWAの場合は、各ユーザーおよびすべてのプロシージャに対して異なる認証ファンクションをコールできます。
パッケージ別認証を使用すると、特定のパッケージのプロシージャまたは匿名プロシージャについてのみ、すべてのユーザーに対して認証ファンクションを実行できます。
たとえば、カスタムOWAを使用している場合、認証ファンクションは、ユーザーがパスワードwelcomeのユーザーguestとしてログインしているかどうかを確認できます。また、ユーザーのIPアドレスをチェックしてアクセス権を判別できます。
表2-2にパラメータ値を示します。
動的認証(DADにユーザー名とパスワードなし)を使用するDADの場合、mod_plsqlではPL/SQLプロシージャを介してユーザーをプログラム的にログオフ(HTTP認証情報を消去)させることができ、すべてのブラウザ・インスタンスを終了する必要はありません。この機能は、Netscape 3.0以上およびMicrosoft Internet Explorerでサポートされます。他のブラウザの場合、ユーザーが認証を解除するにはブラウザの終了操作が必要になることがあります。
ログアウトをシミュレートしてユーザーをサインオフ・ページにリダイレクトする独自のログアウト・プロシージャを作成すると、認証解除をプログラム的に実行できます。
MyLogOffProc
プロシージャを次のように作成または置き換えます。
BEGIN -- Open the HTTP header owa_util.mime_header('text/html', FALSE, NULL); -- Send a cookie to logout owa_cookie.send('WDB_GATEWAY_LOGOUT', 'YES', path=>'/'); -- Close the HTTP header owa_util.http_header_close; -- Generate the page htp.p('You have been logged off from the WEBSITE'); htp.anchor( 'http://www.abc.com', 'click here'); htp.p('<BR>bye'); END;
もう1つの認証解除方法は、URLのDADの後に/logmeoff
を追加することです。たとえば、次のようになります。
http://www.abc.com:2000/pls/myDAD/logmeoff