Oracleの組込みセキュリティ機能およびPHPの使用
著者: Mikhail Seliverstov
Oracle Databaseのネイティブ・セキュリティ機能を利用してPHP Webアプリケーションのセキュリティを改善する方法
2006年3月公開
今日のWebアプリケーションの多くは、少なくとも何らかの基本的なデータ・セキュリティ・ポリシーを実装する必要があります。 たとえば、パスワード保護されたコンテンツを提供するWebサイト、管理専用のバックエンドがあるサイト、ブログおよび個人ジャーナル、電子商取引サイト、企業のイントラネットなどです。
このような種類のWebアプリケーションを構築するのにもっとも一般的で広く使用されている設計手法は、Webアプリケーションのビジネス・ロジックにセキュリティ・ポリシーを組み込むことです。つまり、アプリケーション自体が、特定のユーザーがデータベース内の特定のデータへのアクセス権を持っているかどうかを判断します。 この場合、データベースの役割は、データを保存し、要求に応じて提供することだけに絞られます。 言い換えれば、Webアプリケーションがデータベースの特定の情報を提供するように命令すれば、ユーザーの認可レベルに疑問を示すことなく、データベースはそれに従います。
このレシピでは、アプリケーション全体のセキュリティを強化するために、Oracle Databaseの組込みセキュリティ機能を利用して、データベース・レベルでアプリケーションのセキュリティ・ルールを実行する方法を学ぶことができます。 さらに、データベースにデータ・アクセス・セキュリティを直接実装することで、アプリケーションのセキュリティが向上するだけでなく、その複雑さも軽減することができます。
データベース側セキュリティの必要性
Webアプリケーションからデータ・アクセスを制御するというソリューションの悪い点はどこでしょうか。 ほとんどの場合、悪い点はありません。特に対象のデータがミッション・クリティカルまたは最高機密でない場合は、適正なソリューションです。 この手法は広く採用され、多くの書籍やオンライン・リソースで教えられています。 実際、評判のよいPHP/MySQL参考書の1つでは、アプリケーションごとに複数のデータベース・ユーザー・アカウントを作成することに対して、"余分なユーザーや複雑な権限は、操作を続行する前に多くの情報の確認が必要になるので、MySQLの動作が遅くなる"と明確にアドバスしています。 これは事実ですが、セキュリティをデータベース・ロジックに組み入れる考えを却下する前に、検討してみることがいくつかあります。 次の例を見てみましょう。
コンテンツ管理システム(CMS)を構築していると仮定します。 サイトに公開したコンテンツを保存するために、データベースを使用しています。 ほとんどのデータは公開されており、匿名のWebユーザーが読むことができます。しかし、データ変更は編集者のみに限定する必要があります。 データベース内のレコードへのアクセスおよび変更には1つのデータベース・アカウントを使用し、管理専用ページへのアクセスはパスワードで保護することでPHPコードを使用したセキュリティを制御しています。
Webアプリケーションのパブリック側が、公開されている検索フォーム(つまり、脆弱なコードのフォーム)へのSQLインジェクション攻撃などにより侵害された場合、パブリック・アカウントからアクセスできるデータベース・オブジェクトであればどれでも、侵入者は任意のSQL文を実行できる可能性があります。 データは公開されているため、この場合のSELECT文の実行は大きな問題にはなりません。 しかし、同じデータベース・アカウントを公開アクセス用と管理アクセス用に使用している場合、侵入者はUPDATEおよびDELETE文を発行したり、データベースから表を削除したりすることもできてしまいます。
このようなことを未然に防ぐためにできることとは何でしょうか。 もっとも簡単な解決策は、パブリック・データベース・アカウントからは、データの変更を一切禁止することです。 このような状況を解決するためにOracleが提供すべきことを見ていきましょう。
基本的なOracleセキュリティ概要
OracleデータベースはWeb開発者に、特定のデータベース・オブジェクト(表、ビュー、プロシージャなど)へのアクセス管理から、データの個別の行や列へのアクセス制御まで、データ・アクセスを制御する多くの方法を提供します。 Oracleで利用可能なすべてのセキュリティ機能やオプションについては、このレシピでは説明しません。 詳細に関してはここでは踏み込まず、Oracleのデータ・アクセス・セキュリティのもっとも基本的な側面についてのみ触れていきます。
認証とユーザー・アカウント。ほかのデータベースと同様、Oracleへのアクセスを要求するすべてのユーザー(データベース・アカウント)は認証される必要があります。 認証はデータベース、オペレーティング・システム、またはネットワーク・サービスにより実行することができます。 基本的な認証(パスワード)に加えて、OracleはKerberos、CyberSafe、RADIUS、そのほかの強力な認証メカニズムもサポートします。
ロール。Oracleのロールとは指定された権限のセットです。 ユーザー・アカウントに直接権限を付与できる一方で、特に多数のユーザーを管理する必要がある場合は、ロールを使用するとユーザー管理を大幅に簡略化することができます。 少数の管理しやすいロールを作成して、ユーザーのセキュリティ・レベルに応じたロール(1つまたは複数)のみを各ユーザーに付与することは、非常に効率的です。 権限の変更がさらに容易になることは言うまでもありません。ロールに与えられた権限を変更するだけで、すべてのユーザー・アカウントを変更する必要はありません。
新規ユーザー作成の最初の作業を簡略化するために、Oracleには3つの定義済みロールが備わっています。
- CONNECTロール—Oracleバージョン10g
リリース2(10.2)より前のリリースでは、このロールにより、ユーザーはデータベースに接続し、所有するテーブルやビューの作成などの基本的な機能を実行することができます。 デフォルトでは、このロールは別のユーザーが所有する表にアクセスすることはできません。 しかし10.2では、データベースへの単なる接続に幅広い権限のセットは必要ないという理由で、CONNECTロールに関連付けられたほとんどの権限は削除されました。 現在CONNECTロールに残っている権限はCREATE SESSIONだけです。 この変更により、データベース管理者は最小限の権限の原則に、より適切に従うことができます。 つまり、CONNECTロールを与えられたユーザーはデータベースへアクセスする権利のみを取得しますが、新しい表を作成することはできません。
- RESOURCEロール—RESOURCEロールはさらに多くのシステム権限へのアクセスを付与します。これには、以前CONNECTロールに関連付けられていた権限(表やビューの作成など)や、トリガーまたはストアド・プロシージャの作成などが含まれます。
- DBAロール—すべてのシステム権限へのアクセスを付与します。
権限付与の実例
このセクションでは、セキュリティの向上のため、このレシピの最初に述べた簡単なCMS例を使用してOracleの権限付与の使用方法を説明します。 アプリケーションのユーザーに配布するコンテンツはWEB_CONTENT表に保存されていると仮定します。
最初に、この表を作成する必要があります。 Oracle XEデータベースを開始し、システム管理者としてログインします。 サンプルHRユーザーのロックを解除してない場合は解除してください。 Oracle XEのインストールに含まれている『
Getting Started Guide』の手順に従います。 デフォルトでは、HRユーザーはRESOURCEロールに割り当てられていることに注意してください。 さらに、このユーザーをDBAロールに割り当てることで、このアカウントを使用してCMSアプリケーションのデータベース側を管理できます。 もちろん、オンライン・アクセスのためにHRユーザー・アカウントを使用するのではなく、データベースの管理に限ります。
ここで、オブジェクト・ブラウザを使用するか、またはSQLコマンド・ウィンドウを実行して新しい表を作成できます。 表を作成するコードは以下のとおりです。
CREATE TABLE WEB_CONTENT (
page_id NUMBER PRIMARY KEY,
page_content VARCHAR2(255)
);
HRユーザーとして表を作成したため、表はHRアカウントの所有であり(およびHRスキーマに常駐)、明示的に権限を付与しない限り、ほかのユーザーは現在アクセスできません。 新規ユーザーを作成してWEB_CONTENT表へのアクセスを試行することで、権限をテストすることができます。
ここでは、新規ユーザーCMS_USERおよびCMS_EDITORを作成します。 最終的に、CMS_USERはWEB_CONTENT表に対する読取り専用アクセスを付与され、匿名Webユーザーにコンテンツを配布するデータベース・アカウントとして使用されます。 CMS_EDITORアカウントは、表に対してさらに広い権限を持ち、表のデータ変更および更新が必要なCMS編集者のアカウントとして使用されます。
XEグラフィック・インタフェースを使用するかまたは次のコマンドを実行して、新規ユーザーを作成できます。
CREATE USER cms_user IDENTIFIED BY cms_user;
CREATE USER cms_editor IDENTIFIED BY cms_editor;
(簡略化のため、パスワードとユーザー名を同一にしています)
両アカウントをデータベースにログインできるようにするために、アカウントをCONNECTロールに割り当てる必要があります。 これをおこなうには、XEグラフィック・インタフェースのAdministration/Database Usersセクションのユーザー・プロファイルの下にある「CONNECT」チェックボックスをチェックするか、または次のコマンドを実行します。
GRANT CONNECT to cms_user;
GRANT CONNECT to cms_editor;
ここで、CMS_USERまたはCMS_EDITORのいずれかでログインして、WEB_CONTENT表のデータを読み取ろうとすると(select * from hr.web_content;)、次のエラーが返されます。
ORA-00942: table or view does not exist
データにアクセスするには、単に表を参照するだけであっても、WEB_CONTENT表に対する読取り専用アクセスをCMS_USERおよびCMS_EDITORアカウントの両方に付与する必要があります。
GRANT SELECT on hr.web_content to cms_user;
GRANT SELECT on hr.web_content to cms_editor;
上記のコードにより、両アカウントはWEB_CONTENT表に対しSELECT文を実行することができます。 ほかの文を実行しようとしても、エラーが返されます。 たとえば、行を挿入する場合、
INSERT INTO hr.web_content (page_id,page_content) VALUES (1,'hello world');
次のエラー・メッセージが返されます。
ORA-01031: insufficient privileges
CMS_EDITORアカウントに対して、表のコンテンツの変更を可能にするには、次の権限の付与が必要です(HRで再ログインすることを忘れないでくだい)。
GRANT INSERT,UPDATE,DELETE on hr.web_content to cms_editor;
これでCMS_EDITORアカウントで、WEB_CONTENT表に対しINSERT、UPDATE、DELETE文を実行することができます。 XE組込みセキュリティ・レポートの1つを使用して、簡単に現在のユーザーの権限を確認することができます(「Utilities」->「Object Reports」->「Security」->「User Privileges」->「Object Grants」)。
おわかりのとおり、これは比較的簡単な例です。より効率的な手法が必要な場合は、ロールを使用して権限付与を処理します。 OracleのXE以外のバージョンが稼動している場合、次を実行することができます。
ロールの作成
CREATE ROLE reader;
CREATE ROLE writer;
ロールに権限を付与
GRANT SELECT ON web_content TO reader;
GRANT INSERT,UPDATE,DELETE ON web_content TO writer;
ユーザーのロールへの割当て
GRANT reader TO cms_user;
GRANT reader TO cms_editor; (they need to read too)
GRANT writer TO cms_editor;
今後READERロールの定義を変更する必要がある場合、その変更はこのロールに付与されたすべてのユーザー・アカウントに伝播されることに気をつけてください。 ユーザーに直接権限を付与する場合、ユーザー・アカウントそれぞれを個別に更新する必要があります。
上記の手順の完了後、匿名Webユーザーから要求されたすべてのデータベース接続に対してはCMS_USERアカウントを使用し、パスワードで保護された管理ページからの接続に対してはCMS_EDITORアカウントを使用するように、PHPアプリケーションを設定することができます。 これで、公開されているWebフォームが侵害されたとしても、データベースへの影響は最小限で済みます。CMS_USERアカウントが読取り専用アクセスに制限されているからです。
結論
このレシピでは、Oracleデータ・アクセス・セキュリティのもっとも基本的な機能にのみ触れてきました。 Oracleには、Oracle Virtual Private Database(VPD)やOracle Label Securityなど、Webアプリケーションのセキュリティを新たなレベルに高められる
多くの機能があります。 PHPのコンテキスト内でのVPDについての詳細は、OTNの記事『
Bringing Data Security to PHP Applications』を参照してください。
Mikhail Seliverstovは開発部門のWebプログラミング・チーム・リーダーで、モントリオールのMcGill大学のAlumni Relationsです。 過去3年間、主席アプリケーション・アーキテクトおよび開発者として、大規模なOracle+PHP開発プロジェクトを主導してきました。
ご意見ご感想をお寄せください。
|