アプリケーション開発者のセキュリティ・ポリシーには、パスワード管理、外部プロシージャやアプリケーション権限を保護する方法、アプリケーション・ロールとデータベース・ロールの管理、スキーマ・オブジェクトの保護方法などの領域があります。
内容は次のとおりです。
アプリケーション・セキュリティ・ポリシーは、アプリケーション・セキュリティの要件およびデータベース・オブジェクトへのユーザー・アクセスを規制するルールのリストです。
安全なデータベース・アプリケーションを作成する最初のステップは、アプリケーション・セキュリティ・ポリシーの作成です。セキュリティ・ポリシーは、データベース・アプリケーションごとに立案する必要があります。たとえば、各データベース・アプリケーションには、アプリケーションの実行時に異なるレベルのセキュリティを提供する1つ以上のデータベース・ロールが必要です。データベース・ロールは、他のロールに付与するか、または特定のユーザーに直接付与できます。
(SQL*PlusやSQL Developerなどのツールを使用して)SQL文を制限なしで処理できるアプリケーションの場合でも、機密扱いのスキーマ・オブジェクトや重要なスキーマ・オブジェクトへの不当なアクセスを防ぐために、セキュリティ・ポリシーが必要です。特に、使用するアプリケーションでパスワードが安全に処理されることを確認する必要があります。
アプリケーションのセキュリティを策定して実装する場合、アプリケーション・ユーザーとデータベース・ユーザーを区別することに加えて、アプリケーションまたはデータベースで効果的にセキュリティが実施されているかどうかについて考慮してください。
内容は次のとおりです。
できるかぎり、アプリケーション・ユーザーがデータベース・ユーザーであるアプリケーションを作成し、データベースに備わるセキュリティ・メカニズムを使用できるようにします。
多くの市販のパッケージ・アプリケーションでは、アプリケーション・ユーザーは、データベース・ユーザーではありません。これらのアプリケーションでは、複数のユーザーがユーザー自身をアプリケーションに対して認証し、次に、アプリケーションが単一の高い権限を持つユーザーとしてデータベースに接続します。これを、One Big Application Userモデルと呼びます。
この方法で作成されたアプリケーションは、通常、データベースに本来備わっているセキュリティ機能の多くを使用できません。これは、ユーザーの識別情報がデータベースで認識されないためです。ただし、ある種の追跡はクライアント識別子を使用して実行できます。たとえば、Oracle Call InterfaceメソッドOCIAttrSetのOCI_ATTR_CLIENT_IDENTIFIER属性を使用すると、クライアント接続の監査と監視を有効化できます。クライアント識別子を使用して、個別のWebユーザーの監査証跡データを収集し、Webユーザーによるデータ・アクセスを制限するルールを適用し、各Webユーザーが使用するアプリケーションを監視および追跡できます。
表8-1は、One Big Application Userモデルが様々なOracle Databaseセキュリティ機能にどのように影響するかを説明しています。
表8-1 One Big Application Userモデルの影響を受ける機能
| Oracle Database機能 | One Big Application Userモデルの制限 |
|---|---|
監査 |
セキュリティの基本原則の1つは、監査によるアカウンタビリティです。One Big Application Userがデータベース内のすべての操作を実行する場合、データベース監査では、個々のユーザーが実行したアクションに対する責任をそのユーザー自身に持たせることができません。アプリケーションでは、独自の監査メカニズムを実装して、ユーザーのアクションを個別に捕捉する必要があります。 |
Oracle厳密認証 |
データベースに対するクライアントの認証が、個々のユーザーではなくアプリケーションの場合、認証の厳密な形式(たとえば、SSLやトークンなどでのクライアント認証)は使用できません。 |
ロール |
ロールは、データベース・ユーザーに割り当てられます。エンタープライズ・ロールは、データベース内で作成されていない場合でも、エンタープライズ・ユーザーに割り当てられ、データベースに認識されます。アプリケーション・ユーザーがデータベース・ユーザーではない場合、ロールの有用性は低くなります。この場合、アプリケーションでは独自のメカニズムを作成して、様々なアプリケーション・ユーザーがアプリケーション内のデータへアクセスするのに必要とする権限を識別する必要があります。 |
エンタープライズ・ユーザー管理 |
エンタープライズ・ユーザー管理機能は、Oracle Internet DirectoryなどのLDAPベースのディレクトリにユーザー情報を安全に格納して認可を管理することで、OracleデータベースがOracle Identity Managementインフラストラクチャを使用できるようにします。エンタープライズ・ユーザーは、データベース内に作成する必要はありませんが、データベースに認識される必要があります。One Big Application Userモデルでは、Oracle Identity Managementを利用できません。 |
アプリケーションでできるだけ多くのデータベース・セキュリティ・メカニズムが使用されるようにすることをお薦めします。
ユーザーがデータベース・ユーザーでもあるアプリケーションは、アプリケーションの中にセキュリティを組み込むか、きめ細かい権限、仮想プライベート・データベース(アプリケーション・コンテキストによるファイングレイン・アクセス・コントロール)、ロール、ストアド・プロシージャ、および監査(ファイングレイン監査を含む)などのデータベースに本来備わっているセキュリティ・メカニズムを使用できます。
セキュリティがアプリケーション内ではなくデータベース自体で規定されている場合は、セキュリティを回避することはできません。アプリケーション・ベースのセキュリティの主なデメリットは、ユーザーがアプリケーションを回避してデータにアクセスすると、セキュリティが回避されることです。たとえば、データベースへのSQL*Plusアクセス権を持つユーザーは、人事管理アプリケーションを介さずに問合せを実行できます。したがって、このユーザーは、アプリケーション内のセキュリティ対策のすべてをバイパスします。
One Big Application Userモデルを使用するアプリケーションでは、データベースのセキュリティ・メカニズムを使用せずに、アプリケーション内にセキュリティ規定を作成する必要があります。ユーザーを認識するのは、データベースではなくアプリケーションであるため、アプリケーション自体が各ユーザーに対してセキュリティ対策を規定する必要があります。
このアプローチでは、データにアクセスする各アプリケーションでのセキュリティの再実装が必要になります。組織では複数のアプリケーションに同じセキュリティ・ポリシーを実装する必要があるため、セキュリティが高コストになり、新規アプリケーションごとに高コストな再実装が必要になります。
Oracle Databaseには、バッチ・ジョブ、スクリプト、インストール・ファイルまたはアプリケーションからパスワードで保護されたサービスを安全に起動する戦略が用意されています。パスワード保護に加えて、これらの戦略の多くはその他の機密データ(暗号化鍵など)に適用できます。
内容は次のとおりです。
関連項目:
Oracleデータベースの保護に関する一般的なガイドラインについては、Oracle Databaseの安全性の維持を参照してくださいアプリケーションでのパスワード保護のガイドラインでは、プラットフォーム固有のセキュリティ脅威、パスワード入力、パスワードの形式と動作、SQL*PlusおよびSQLスクリプトでのパスワードの取扱い方法が取り上げられています。
内容は次のとおりです。
次の潜在的なセキュリティへの脅威は、わかりにくい可能性があるので注意してください。
これらのセキュリティへの脅威は次のとおりです。
UNIXおよびLinuxプラットフォームでは、同じホスト・コンピュータ上のすべてのオペレーティング・システム・ユーザーがコマンド・パラメータを表示できます。結果として、コマンドラインに入力したパスワードは他のユーザーに公開される可能性があります。ただし、UNIXおよびLinux以外のプラットフォームがこの脅威を回避できるとは考えないでください。
HP Tru64およびIBM AIXなど一部のUNIXプラットフォームでは、すべてのオペレーティング・システム・ユーザーがあらゆるプロセスの環境変数を表示できます。ただし、UNIXおよびLinux以外のプラットフォームがこの脅威を回避できるとは考えないでください。
Microsoft Windowsでは、コマンド・リコール機能(上矢印)に、コマンド起動間のユーザー入力が記憶されます。たとえば、SQL*PlusのCONNECT SYSTEM/password表記法を使用し、終了してから上矢印を押してCONNECTコマンドを繰り返した場合、コマンド・リコール機能により接続文字列が明らかになり、パスワードが表示されます。また、Microsoft Windows以外のプラットフォームがこの脅威を回避できるとは考えないでください。
Oracleには、パスワード入力を扱うアプリケーションの設計に関するガイドラインが用意されています。
パスワードの入力を対話形式で求めるアプリケーションを設計します。コマンドライン・ユーティリティの場合、コマンド・プロンプトでパスワードを公開することをユーザーに強制しないでください。
アプリケーションの設計に使用するプログラミング言語のAPIについて、ユーザーからのパスワードを処理する最適な方法を確認します。この機能を処理するJavaコードの例は、「例: パスワードを読み取るためのJavaコード」を参照してください。
コード・インジェクション攻撃からデータベースを保護します。コード・インジェクション攻撃の標的は主に、データベースにSQLを送信するクライアント・アプリケーション・ツール(SQL*Plus、Oracle Call Interface (OCI)、JDBCアプリケーションなど)です。これらのツールを使用して作成されたデータベース・ドライバも含まれます。SQLインジェクション攻撃では、PL/SQLアプリケーションで想定されていない方法でSQL文が動作します。インジェクション攻撃は、データベースに文が送信される前に行われます。たとえば、侵入者はWHERE句をTRUEに設定してパスワード認証を回避できます。
SQLインジェクション攻撃の問題に対処するには、バインド変数引数を使用するか妥当性チェックを作成します。バインド変数を使用できない場合は、DBMS_ASSERT PL/SQLパッケージを使用して入力値のプロパティを検証することを検討してください。DBMS_ASSERTパッケージの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。また、PUBLICなどのロールに対する権限付与も検討してください。
インジェクションはデータベースに文が送信される前に行われる可能性があるため、クライアント・アプリケーションのユーザーがSQLインジェクションをPL/SQLに結び付けることができるとは限らないことに注意してください。
SQLインジェクションの防止の詳細は、『Oracle Database PL/SQL言語リファレンス』を参照してください。
可能な場合は、認証を遅延するアプリケーションを設計します。次に例を示します。
ログインに証明書を使用します。
オペレーティング・システムで提供される機能を使用してユーザーを認証します。たとえば、Microsoft Windows上で動作するアプリケーションはドメイン認証を使用できます。
パスワードをマスクまたは暗号化します。パスワードを格納する必要がある場合、パスワードをマスクまたは暗号化します。たとえば、ログ・ファイルでパスワードをマスクし、リカバリ・ファイルでパスワードを暗号化できます。
各接続を認証します。たとえば、スキーマAがデータベース1に存在する場合、データベース2のスキーマAが同一のユーザーであるとは考えないでください。同様に、ローカル・オペレーティング・システム・ユーザーpsmithは、必ずしもリモート・ユーザーpsmithと同じユーザーではありません。
ファイルまたはリポジトリにクリアテキスト・パスワードを格納しないでください。パスワードをファイルに格納すると、侵入者がパスワードにアクセスする危険性が高まります。
1つのマスター・パスワードを使用します。次に例を示します。
1人のデータベース・ユーザーに、他のデータベース・ユーザーとなるためのプロキシ認証を付与できます。この場合、必要となるデータベース・パスワードは1つのみです。詳細は、「プロキシ・ユーザー・アカウントと、そのアカウントを介して接続するユーザーの認可」を参照してください。
マスター・パスワードでオープンできるパスワード・ウォレットを作成できます。ウォレットにはその他のパスワードが含められます。Wallet Managerの詳細は、『Oracle Databaseエンタープライズ・ユーザー・セキュリティ管理者ガイド』を参照してください。
Oracle Databaseには、パスワードの形式と動作の構成に関するガイドラインが用意されています。
パスワードの存続期間を制限します。パスワード存続期間を設定して、その期間が過ぎるとパスワードが期限切れになり、変更しないとユーザーがアカウントにログインできなくなるようにすることができます。パスワードの存続期間を制御するために使用できるパラメータは、パスワード・エイジングおよび期限切れの制御についてを参照してください。
ユーザーが古いパスワードを再利用する機能を制限します。詳細は、ユーザーによる以前のパスワードの再利用の制御を参照してください。
強力かつ安全なパスワードを作成するようユーザーに要求します。強力なパスワードの作成に関するガイドラインは、パスワードの保護に関するガイドラインを参照してください。パスワードの複雑度検証の概要では、パスワードの要件をカスタマイズする方法について説明しています。
パスワードで大/小文字を区別できるようにします。詳細は、パスワードでの大/小文字の区別の管理を参照してください。
関連項目:
Oracleには、SQLスクリプトにおけるパスワードの取扱いに関するガイドラインが用意されています。
プログラムまたはスクリプトのコマンドラインにパスワードを指定してSQL*Plusを起動しないでください。パスワードが必須であるにもかかわらず省略した場合、SQL*Plusではパスワードの入力を求めるプロンプトが表示され、パスワードが表示されないようにエコー機能が自動的に無効となります。
次の各例は、パスワードがコマンドライン上で公開されないため安全です。また、Oracle Databaseではこれらのパスワードがネットワークを介して自動的に暗号化されます。
$ sqlplus system Enter password: password SQL> CONNECT SYSTEM Enter password: password
次の例では、パスワードが他のオペレーティング・システム・ユーザーに公開されます。
sqlplus system/password
次の例は、2つのセキュリティ上のリスクをもたらします。1つ目の例では、覗き込んでいる可能性のある他のユーザーにパスワードを公開してしまいます。2つ目の例では、Microsoft Windowsなどの一部のプラットフォームにおいて、パスワードがコマンドラインのリコール攻撃を受けやすくなります。
$ sqlplus /nolog
SQL> CONNECT SYSTEM/password
たとえばパスワードまたは秘密鍵を必要とするSQLスクリプトの場合、アカウントを作成したりあるアカウントでログインするには、置換変数&1、&2などの位置パラメータを使用しないでください。かわりに、ユーザーに値の入力を求めるプロンプトを表示するスクリプトを設計します。また、スクリプトから、またはスプール・モードを使用している場合に出力を表示するエコー機能を無効にする必要があります。エコー機能を無効にするには、次の設定を使用します。
SET ECHO OFF
スクリプトにより値の目的を明白にする必要があります。たとえば、値によりアカウントまたは証明書などの新しい値が設定されるかどうか、または既存のアカウントへのログインなど、値が認証されるかどうかを明白にする必要があります。
次の例は、セキュリティ上のリスクをもたらす方法でユーザーがスクリプトを起動することが回避されるため安全です。パスワードはエコーされず、スプール・ファイルに記録されません。
SET VERIFY OFF ACCEPT user CHAR PROMPT ‘Enter user to connect to: ‘ ACCEPT password CHAR PROMPT ‘Enter the password for that user: ' HIDE CONNECT &user/&password
この例の説明は、次のとおりです。
SET VERIFY OFFは、パスワードの表示を防止します。(SET VERIFYは、置換の前後にスクリプトの各行をリストします。)SET VERIFY OFFコマンドをHIDEコマンドと結合する方法は、パスワードおよびその他の機密入力データを非表示にする便利なテクニックです。
ACCEPT password CHAR PROMPTは、ACCEPT passwordプロンプトにHIDEオプションを含めます。これによって入力パスワードのエコーが回避されます。
次の例では位置パラメータを使用しており、ユーザーがコマンドライン上でパスワードを渡すことでスクリプトを起動できるため、セキュリティ上のリスクをもたらします。ユーザーがパスワードを入力せず、入力を求めるプロンプトが表示される場合、ユーザーが入力した内容がすべて画面およびスプール・ファイル(スプールが有効な場合)にエコーされるため危険です。
CONNECT &1/&2
バッチ・スクリプトのログイン時間を制御します。パスワードを必要とするバッチ・スクリプトでは、実行されることになっている時間内のみにバッチ・スクリプトがログインできるようにアカウントを構成します。たとえば、毎日午後8時から1時間実行するバッチ・スクリプトを想定します。この時間のみスクリプトがログインできるようにアカウントを設定します。侵入者がアクセスしようとした場合、安全性の低いアカウントが利用される可能性は低くなります。
パスワードの入力を求めるDML文またはDDL SQL文を使用する場合は注意してください。この場合、機密情報がネットワークを介してクリアテキストで渡されます。Oracle厳密認証を使用して、この問題に対処できます。
次のパスワード変更例は、パスワードが公開されないため安全です。
password psmith Changing password for psmith New password: password Retype new password: password
この例は、パスワードがコマンドラインおよびネットワーク上の両方に公開されるため、セキュリティ上のリスクをもたらします。
ALTER USER psmith IDENTIFIED BY password
データベースに接続するためのパスワード資格証明は、クライアント側のOracleウォレットを使用して格納できます。
Oracleウォレットは、ユーザーのログインに必要な認証および署名用証明書を格納する安全性の高いソフトウェア・コンテナです。
関連項目:
安全性の高い外部パスワード・ストアの詳細は、パスワード資格証明用の安全性の高い外部パスワード・ストアの管理を参照してください
Oracle Wallet Managerを使用したOracleウォレットの構成の詳細は、『Oracle Databaseエンタープライズ・ユーザー・セキュリティ管理者ガイド』を参照してください。
SYSDBAまたはSYSOPERユーザーはパスワード・ファイルを使用して、ネットワーク経由でアプリケーションに接続できます。
パスワード・ファイルを作成するには、ORAPWDユーティリティを使用します。
関連項目:
パスワード・ファイルの作成および管理方法の詳細は、『Oracle Database管理者ガイド』を参照してください。
パスワードの読取りに使用できるJavaパッケージを作成できます。
例8-1に、パスワードの読取りに使用できるJavaパッケージの作成方法を示します。
例8-1 パスワードを読み取るためのJavaコード
// Change the following line to a name for your version of this package
package passwords.sysman.emSDK.util.signing;
import java.io.IOException;
import java.io.PrintStream;
import java.io.PushbackInputStream;
import java.util.Arrays;
/**
* The static readPassword method in this class issues a password prompt
* on the console output and returns the char array password
* entered by the user on the console input.
*/
public final class ReadPassword {
//----------------------------------
/**
* Test driver for readPassword method.
* @param args the command line args
*/
public static void main(String[] args) {
char[] pass = ReadPassword.readPassword("Enter password: ");
System.out.println("The password just entered is \""
+ new String(pass) + "\"");
System.out.println("The password length is " + pass.length);
}
* Issues a password prompt on the console output and returns
* the char array password entered by the user on the console input.
* The password is not displayed on the console (chars are not echoed).
* As soon as the returned char array is not needed,
* it should be erased for security reasons (Arrays.fill(charArr, ' '));
* A password should never be stored as a java String.
*
* Note that Java 6 has a Console class with a readPassword method,
* but there is no equivalent in Java 5 or Java 1.4.
* The readPassword method here is based on Sun's suggestions at
* http://java.sun.com/developer/technicalArticles/Security/pwordmask.
*
* @param prompt the password prompt to issue
* @return new char array containing the password
* @throws RuntimeException if some error occurs
*/
public static final char[] readPassword(String prompt)
throws RuntimeException {
try {
StreamMasker masker = new StreamMasker(System.out, prompt);
Thread threadMasking = new Thread(masker);
int firstByte = -1;
PushbackInputStream inStream = null;
try {
threadMasking.start();
inStream = new PushbackInputStream(System.in);
firstByte = inStream.read();
} finally {
masker.stopMasking();
}
try {
threadMasking.join();
} catch (InterruptedException e) {
throw new RuntimeException("Interrupt occurred when reading password");
}
if (firstByte == -1) {
throw new RuntimeException("Console input ended unexpectedly");
}
if (System.out.checkError()) {
throw new RuntimeException("Console password prompt output error");
}
inStream.unread(firstByte);
return readLineSecure(inStream);
}
catch (IOException e) {
throw new RuntimeException("I/O error occurred when reading password");
}
}
//----------------------------------
/**
* Reads one line from an input stream into a char array in a secure way
* suitable for reading a password.
* The char array will never contain a '\n' or '\r'.
*
* @param inStream the pushback input stream
* @return line as a char array, not including end-of-line-chars;
* never null, but may be zero length array
* @throws RuntimeException if some error occurs
*/
private static final char[] readLineSecure(PushbackInputStream inStream)
throws RuntimeException {
if (inStream == null) {
throw new RuntimeException("readLineSecure inStream is null");
}
try {
char[] buffer = null;
try {
buffer = new char[128];
int offset = 0;
// EOL is '\n' (unix), '\r\n' (windows), '\r' (mac)
loop:
while (true) {
int c = inStream.read();
switch (c) {
case -1:
case '\n':
break loop;
case '\r':
int c2 = inStream.read();
if ((c2 != '\n') && (c2 != -1))
inStream.unread(c2);
break loop;
default:
buffer = checkBuffer(buffer, offset);
buffer[offset++] = (char) c;
break;
}
}
char[] result = new char[offset];
System.arraycopy(buffer, 0, result, 0, offset);
return result;
}
finally {
if (buffer != null)
Arrays.fill(buffer, ' ');
}
}
catch (IOException e) {
throw new RuntimeException("I/O error occurred when reading password");
}
}
//----------------------------------
/**
* This is a helper method for readLineSecure.
*
* @param buffer the current char buffer
* @param offset the current position in the buffer
* @return the current buffer if it is not yet full;
* otherwise return a larger buffer initialized with a copy
* of the current buffer and then erase the current buffer
* @throws RuntimeException if some error occurs
*/
private static final char[] checkBuffer(char[] buffer, int offset)
throws RuntimeException
{
if (buffer == null)
throw new RuntimeException("checkBuffer buffer is null");
if (offset < 0)
throw new RuntimeException("checkBuffer offset is negative");
if (offset < buffer.length)
return buffer;
else {
try {
char[] bufferNew = new char[offset + 128];
System.arraycopy(buffer, 0, bufferNew, 0, buffer.length);
return bufferNew;
} finally {
Arrays.fill(buffer, ' ');
}
}
}
//----------------------------------
/**
* This private class prints a one line prompt
* and erases reply chars echoed to the console.
*/
private static final class StreamMasker
extends Thread {
private static final String BLANKS = StreamMasker.repeatChars(' ', 10);
private String m_promptOverwrite;
private String m_setCursorToStart;
private PrintStream m_out;
private volatile boolean m_doMasking;
//----------------------------------
/**
* Constructor.
* @throws RuntimeException if some error occurs
*/
public StreamMasker(PrintStream outPrint, String prompt)
throws RuntimeException {
if (outPrint == null)
throw new RuntimeException("StreamMasker outPrint is null");
if (prompt == null)
throw new RuntimeException("StreamMasker prompt is null");
if (prompt.indexOf('\r') != -1)
throw new RuntimeException("StreamMasker prompt contains a CR");
if (prompt.indexOf('\n') != -1)
throw new RuntimeException("StreamMasker prompt contains a NL");
m_out = outPrint;
m_setCursorToStart = StreamMasker.repeatChars('\010',
prompt.length() + BLANKS.length());
m_promptOverwrite = m_setCursorToStart + prompt + BLANKS
+ m_setCursorToStart + prompt;
}
//----------------------------------
/**
* Begin masking until asked to stop.
* @throws RuntimeException if some error occurs
*/
public void run()
throws RuntimeException {
int priorityOriginal = Thread.currentThread().getPriority();
Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
try {
m_doMasking = true;
while (m_doMasking) {
m_out.print(m_promptOverwrite);
if (m_out.checkError())
throw new RuntimeException("Console output error writing prompt");
try {
Thread.currentThread().sleep(1);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
return;
}
}
m_out.print(m_setCursorToStart);
} finally {
Thread.currentThread().setPriority(priorityOriginal);
}
}
//----------------------------------
/**
* Instructs the thread to stop masking.
*/
public void stopMasking() {
m_doMasking = false;
}
//----------------------------------
/**
* Returns a repeated char string.
*
* @param c the char to repeat
* @param length the number of times to repeat the char
* @throws RuntimeException if some error occurs
*/
private static String repeatChars(char c, int length)
throws RuntimeException {
if (length < 0)
throw new RuntimeException("repeatChars length is negative");
StringBuffer sb = new StringBuffer(length);
for (int i = 0; i < length; i++)
sb.append(c);
return sb.toString();
}
}
}
外部プロシージャは、データベースとは別に、.dllまたは.soファイルに格納されるプロシージャです。外部プロシージャを保護するには、資格証明を介してその外部プロシージャを認証できます。
内容は次のとおりです。
安全上の理由のため、Oracle外部プロシージャは、データベースと物理的に異なるプロセスで実行されます。
ほとんどの場合、このプロセスを構成して、Oracleソフトウェア・アカウント以外のユーザーとして実行します。アプリケーションがこの外部プロシージャを呼び出す場合(.dllまたは.soファイルのライブラリにアクセスする必要がある場合など)、Oracle Databaseがextprocと呼ばれるオペレーティング・システム・プロセスを作成します。デフォルトでは、extprocプロセスは、サーバー・プロセスで直接通信します。つまり、資格証明を使用しない場合、Oracle Databaseは、デフォルトのOracle Databaseサーバー構成でextprocプロセスを作成し、oracleソフトウェア・アカウントとしてextprocを実行します。また、Oracle Databaseリスナーを介して通信できます。
セキュリティを強化するために、extprocプロセスを構成して、資格証明を介して認証できます。
一般プロセスは次のとおりです。
資格証明を作成します。
資格証明は、暗号化されたコンテナにあります。パブリック・シノニムとプライベート・シノニムの両方でこの資格証明を参照できます。「外部プロシージャの認証の構成」では、この資格証明を作成し、データベースを構成して使用する方法について説明します。
専用サーバーまたは共有サーバー・プロセスで実行しているデータベースへの最初の接続を行います。
アプリケーションは、外部プロシージャへのコールを行います。
これが最初のコールの場合、Oracle Databaseはextprocプロセスを作成します。extprocの資格証明を使用する場合、Oracleリスナーを使用してextprocプロセスを起動できません。
extprocプロセスは、偽装(つまり、指定された資格証明のかわりに実行)して、必要な.dll、.so、.slまたは.aファイルをロードし、SQLおよびC間のデータを送信します。
extprocプロセスには、認証および偽装に対する一連の動作が含まれています。
表8-2では、可能性のある認証および偽装シナリオに基づくextprocプロセスの予期される動作について説明します。
表8-2 extprocプロセス認証および偽装設定の予期される動作
| ENFORCE_CREDENTIAL環境変数設定 | 資格証明を使用したPL/SQLライブラリか | GLOBAL_EXTPROC_CREDENTIAL資格証明の有無(1) | 予期される動作 |
|---|---|---|---|
|
なし |
なし |
OracleリスナーまたはOracleサーバー・プロセスの所有者のオペレーティング・システム権限で認証される12cより前のリリースの認証を使用します。 |
|
なし |
あり |
Oracleインスタンス全体の指定された |
|
あり |
なし |
PL/SQLライブラリで定義された資格証明を使用して認証および偽装します |
|
あり |
あり |
認証および偽装します(脚注3) |
|
なし |
なし |
|
|
なし |
あり |
Oracleシステム全体の指定された |
|
あり |
なし |
PL/SQLライブラリで定義された資格証明を使用して認証および偽装します |
|
あり |
あり |
認証および偽装します(脚注2) |
脚注1 資格証明が明示的に指定されず、ENFORCE_CREDENTIAL環境変数がTRUEに設定されている場合、GLOBAL_EXTPROC_CREDENTIALは、デフォルトの資格証明の予約された資格証明名です。そのため、ENFORCE_CREDENTIALがTRUEに設定されている場合、この名前で資格証明を作成することをお薦めします。
脚注2
GLOBAL_EXTPROC_CREDENTIAL資格証明のみを使用している場合、このグローバル資格証明のEXECUTE権限が暗黙的にすべてのユーザーに自動的に付与されます。
脚注3
PL/SQLライブラリおよびGLOBAL_EXTPROC_CREDENTIAL設定の両方で資格証明が定義された場合、PL/SQLライブラリの資格証明が優先されます。
extprocプロセスの資格証明を構成するには、DBMS_CREDENTIAL PL/SQLパッケージを使用します。
関連項目:
DBMS_CREDENTIALパッケージの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。
extprocエージェントの詳細は、『Oracle Call Interfaceプログラマーズ・ガイド』を参照してください。
extproc.oraファイルの詳細は、『Oracle Database Net Services管理者ガイド』を参照してください。
セキュリティを最大にするために、ENFORCE_CREDENTIAL環境変数をTRUEに設定します。
ただし、下位互換性に対応する必要がある場合、ENFORCE_CREDENTIALをFALSEに設定します。FALSEによって、extprocプロセスは、指定された資格証明のかわりにユーザー定義コールアウト関数を認証、偽装および実行できます。
資格証明がPL/SQLライブラリで定義されます。
資格証明は定義されていませんが、 GLOBAL_EXTPROC_CREDENTIAL資格証明が存在します。
これらの資格証明定義が設定されていない場合、ENFORCE_CREDENTIALパラメータをFALSEに設定すると、OracleリスナーまたはOracleサーバー・プロセスの所有者のオペレーティング・システム権限で認証されるextprocプロセスが設定されます。
extprocプロセス上で実行されるレガシー・アプリケーションでは、レガシー・アプリケーション・コードを変更して、すべての別名ライブラリと資格証明を関連付けることをお薦めします。これを実行できない場合、Oracle DatabaseはGLOBAL_EXTPROC_CREDENTIAL資格証明を使用して、認証の処理方法を決定します。GLOBAL_EXTPROC_CREDENTIAL資格証明が定義されていない場合、extprocプロセスは、OracleリスナーまたはOracleサーバー・プロセスの所有者のオペレーティング・システム権限で認証されます。
ほとんどのデータベース・アプリケーションでは、異なるスキーマ・オブジェクトごとに異なる権限が関与します。
各アプリケーションに必要な権限の追跡は、複雑な場合があります。また、アプリケーションを実行するユーザーの認可には、多くのGRANT操作が関与する場合があります。
アプリケーションの権限管理を簡素化するために、アプリケーションごとに作成した1つのロールに、1人のユーザーがそのアプリケーションを実行するために必要なすべての権限を付与します。
実際には、1つのアプリケーションに複数のロールがある可能性があり、各ロールには、アプリケーションの実行中に使用できる機能の多少を決める権限の特定サブセットが付与されます。
たとえば、すべての管理アシスタントが休暇アプリケーションを使用して、部門のメンバーが取得した休暇を記録するとします。このアプリケーションを効率的に管理するには、次の操作手順が必要です。
VACATIONロールを作成します。VACATIONロールに付与します。VACATIONロールをすべての管理アシスタントに付与します。より効率的な方法は、管理アシスタントが持つ権限を定義したロールを作成し、VACATIONロールをそのロールに付与します。 関連項目:
ロールの作成、使用可能化と使用禁止化、および権限の付与と取消しの詳細は、「権限とロール認可の構成」を参照してください。
ROLE_TAB_PRIVS、ROLE_SYS_PRIVSおよびDBA_ROLE_PRIVSデータ・ディクショナリ・ビューのセキュリティ使用の詳細は、ユーザー権限およびロールのデータ・ディクショナリ・ビューを参照してください
複数のアプリケーション権限を1つのロールにグループ化すると、権限の管理に役立ちます。
次の管理オプションを考えてみます。
アプリケーションを実行するユーザーに、多数の個別の権限ではなく、ロールを付与できます。したがって、従業員が業務を変更するときは、多くの権限ではなく、1つのロールのみを付与または取り消す必要があります。
アプリケーションに対応付けられている権限の変更は、そのアプリケーションのすべてのユーザーが保持する権限ではなく、ロールに付与されている権限のみを修正することで実行できます。
特定のアプリケーションの実行に必要な権限は、ROLE_TAB_PRIVSとROLE_SYS_PRIVSの各データ・ディクショナリ・ビューを問い合せることで判断できます。
どのユーザーに、どのアプリケーションの権限があるかは、DBA_ROLE_PRIVSデータ・ディクショナリ・ビューを問い合せることで判断できます。
セキュア・アプリケーション・ロールは関連するPL/SQLパッケージまたはプロシージャでのみ使用可能にできます。
内容は次のとおりです。
関連項目:
セキュア・アプリケーション・ロールの作成例は、『Oracle Database 2日でセキュリティ・ガイド』を参照してください
IDENTIFIED USING句を持つCREATE ROLE文で、セキュア・アプリケーション・ロールを作成します。
この文を実行するには、CREATE ROLEシステム権限が必要です。
たとえば、sec_mgr.hr_adminパッケージに対応付けられるhr_adminというセキュア・アプリケーション・ロールを作成するには、次の手順を実行します。
アプリケーションに対するアクセス・ポリシーを定義するPL/SQLパッケージを作成できます。
内容は次のとおりです。
セキュア・アプリケーション・ロールを有効または無効にするには、PL/SQLパッケージ内にロールのセキュリティ・ポリシーを作成する必要があります。
個別のプロシージャを作成してこれを実行することもできますが、パッケージを使用すると、一連のプロシージャをグループ化できます。これにより、一緒に使用するポリシーのグループを作成して、アプリケーションを保護するための強固なセキュリティ戦略を提示できます。セキュリティ・ポリシーに失敗したユーザー(潜在的な侵入者)については、監査チェックをパッケージに追加して、その失敗を記録できます。通常、このパッケージは、セキュリティ管理者のスキーマに作成します。
このパッケージまたはプロシージャは、次の内容を実行する必要があります。
実行者権限を使用してロールを有効にする必要があります。実行者権限を使用してパッケージを作成するには、AUTHIDプロパティをCURRENT_USERに設定する必要があります。定義者権限を使用してパッケージを作成することはできません。
実行者権限と定義者権限の詳細は、『Oracle Database PL/SQL言語リファレンス』を参照してください。
ユーザーを検証するためのセキュリティ・チェックを1つ以上組み込む必要があります。ユーザーを検証する方法の1つは、SYS_CONTEXT SQLファンクションを使用することです。SYS_CONTEXTの詳細は、Oracle Database SQL言語リファレンスを参照してください。ユーザーに関するセッション情報を検索するために、アプリケーション・コンテキストでSYS_CONTEXTを使用できます。詳細は、「アプリケーション・コンテキストを使用したユーザー情報の取得」を参照してください。
ユーザーがセキュリティ・チェックを通過するときにSET ROLE SQL文またはDBMS_SESSION.SET_ROLEプロシージャを発行する必要があります。パッケージは実行者権限を使用して作成するため、SET ROLE SQL文またはDBMS_SESSION.SET_ROLEプロシージャを発行することによりロールを設定する必要があります。(ただし、このタイプのロール有効化でSET ROLE ALL文を使用することはできません。)PL/SQL埋込みSQL構文はSET ROLE文をサポートしませんが、動的SQL(たとえばEXECUTE IMMEDIATEにより)を使用することによりSET ROLEを起動できます。
EXECUTE IMMEDIATEの詳細は、『Oracle Database PL/SQL言語リファレンス』を参照してください。
このパッケージまたはプロシージャの作成方法が原因で、セキュア・アプリケーション・ロールを使用可能または使用禁止にする際にログイン・トリガーを使用できません。かわりに、ユーザーがセキュリティ・アプリケーション・ロールで付与された権限を使用する前のユーザー・ログイン時に、アプリケーションからパッケージを直接起動します。
作成するPL/SQLパッケージまたはプロシージャでは、アクセス・ポリシーを定義するために実行者権限を使用する必要があります。
たとえば、hr_adminロールを使用する全員を、オンサイト(特定の端末を使用)で午前8時から午後5時まで勤務する従業員に限定するとします。システム管理者またはセキュリティ管理者として、アプリケーションに対してアクセス・ポリシーを定義するプロシージャを作成できます。
セキュア・アプリケーション・ロールを付与されたユーザーとして、そのロールで付与される権限を要するアクションを実行します。
セキュア・アプリケーション・ロールを付与されたユーザーとしてログインすると、そのロールが有効になります。
そのユーザーとしてデータベース・セッションにログインします。
例:
CONNECT PSMITH@hrpdb
Enter password: password
セキュア・アプリケーション・ロールで付与される権限を要求するアクションを実行します。
たとえば、そのロールがsec_admin.hr_admin_role_checkプロシージャに対してEXECUTE権限を付与するとします。
EXECUTE sec_admin.hr_admin_role_check;
ユーザーの権限が、現在のデータベース・ロールに関連した権限のみであることを確認します。
内容は次のとおりです。
1人のユーザーが、多数のアプリケーションおよび多数の対応付けられたロールを使用できます。
ただし、このユーザーの権限は、現在のデータベース・ロールに関連した権限のみであることを確認する必要があります。
次の使用例を考えてみます。
(「受注」というアプリケーションの)ORDERロールには、INVENTORY表に対するUPDATE権限が含まれています。
(「在庫」というアプリケーションの)INVENTORYロールには、INVENTORY表に対するSELECT権限が含まれています。
何人かの受注入力担当には、ORDERロールとINVENTORYロールの両方が付与されています。
このシナリオでは、両方のロールを付与された受注入力担当がINVENTORYアプリケーションの実行時にORDERロールの権限を使用してINVENTORY表を更新できます。問題は、INVENTORY表の更新は、INVENTORYアプリケーションにとって承認された操作ではないということです。ORDERアプリケーションにとって承認された操作です。この問題を防ぐには、SET ROLE文を次のセクションの説明のとおりに使用します。
各アプリケーションの開始時にSET ROLE文を使用して、各アプリケーションに対応付けられているロールを自動的に使用可能にし、他のすべてのロールを使用禁止にします。
この方法によって、各アプリケーションでは、必要な場合にのみ、ユーザーの特定の権限を動的に使用可能にします。SET ROLE文は、権限の管理を簡素化します。ユーザーがどのような情報にアクセスできるかと、その情報にいつアクセスできるかを制御します。また、このSET ROLE文によって、ユーザーは、明確に定義された権限ドメイン内で操作を続行できます。あるユーザーがロールからのみ権限を取得している場合、そのユーザーはこれらの権限を組み合せて不正な操作を実行することはできません。
関連項目:
ロールの使用可能および使用禁止の詳細は、権限の付与と取消しが有効になるときを参照してください
スキーマとは、データベース・オブジェクトを含めることができるセキュリティ・ドメインです。各ユーザーまたはロールに付与された権限によって、これらのデータベース・オブジェクトへのアクセスが制御されます。
内容は次のとおりです。
ほとんどのスキーマはユーザー名と考えることができます。つまり、ユーザーがデータベースに接続してそのデータベース・オブジェクトへのアクセスを可能にするアカウントです。
ただし、一意スキーマではデータベースへの接続は許可されませんが、関連する一連のオブジェクトを格納するために使用されます。この種のスキーマは通常ユーザーとして作成されますが、CREATE SESSIONシステム権限は(明示的にもロールを介しても)付与されません。
オブジェクトを保護するには、CREATE SCHEMAを使用して、1つのトランザクション内に複数の表とビューを作成する場合は、一意スキーマにCREATE SESSIONおよびRESOURCE権限を一時的に付与します。
たとえば、所定のスキーマが特定のアプリケーションのスキーマ・オブジェクトを所有する場合があります。アプリケーション・ユーザーに権限がある場合、そのユーザーは、一般的なデータベース・ユーザー名を使用してデータベースに接続し、アプリケーションとそれに対応するオブジェクトを使用できます。ただし、ユーザーはアプリケーションに設定されたスキーマを使用して、データベースに接続することはできません。この構成は、対応付けられたオブジェクトへのスキーマを介したアクセスを防ぎ、スキーマ・オブジェクトの保護を強化します。この場合、アプリケーションではALTER SESSION SET CURRENT_SCHEMA文を発行して、ユーザーを適切なアプリケーション・スキーマに接続できます。
多くのアプリケーションでは、ユーザーがアクセスする必要があるのはアプリケーション・スキーマのみであるため、データベースで自分自身のアカウントつまりスキーマを必要としません。
たとえば、ユーザーJohn、FiruzehおよびJaneはすべて給与アプリケーションのユーザーで、financeデータベースのpayrollスキーマにアクセスする必要があるとします。この場合、データベースに自分自身のオブジェクトを作成する必要があるユーザーはいません。これらのユーザーに必要なのは、payrollオブジェクトへのアクセスのみです。この問題に対処するために、Oracle Databaseではエンタープライズ・ユーザー(スキーマに依存しないユーザー)が提供されています。
エンタープライズ・ユーザー、つまりディレクトリ・サービスで管理されるユーザーは、共有データベース・スキーマを使用するため、データベース・ユーザーとして作成する必要はありません。管理コストを削減するために、管理者はディレクトリに1つのエンタープライズ・ユーザーを1回作成し、他の多数のユーザーもアクセスできる共有スキーマで、そのユーザーを指し示すことができます。
関連項目:
エンタープライズ・ユーザーの管理の詳細は、『Oracle Databaseエンタープライズ・ユーザー・セキュリティ管理者ガイド』を参照してください。
アプリケーション設計の一部として、そのアプリケーションで作業するユーザーのタイプ、およびユーザーが担当のタスクを達成するために必要なアクセスのレベルを決定する必要があります。
内容は次のとおりです。
オブジェクト権限によって、エンド・ユーザーは、表、ビュー、順序、プロシージャ、ファンクション、パッケージなどのオブジェクトに対してアクションを実行できます。
表8-3に、オブジェクトの各タイプで使用できるオブジェクト権限の概要を示します。
表8-3 権限とスキーマ・オブジェクトとの関連
| オブジェクト権限 | 表への適用 | ビューへの適用 | 順序への適用 | プロシージャへの適用(4) |
|---|---|---|---|---|
|
あり |
なし |
あり |
なし |
|
あり |
あり |
なし |
なし |
|
なし |
なし |
なし |
あり |
|
あり脚注5 |
なし |
なし |
なし |
|
あり |
あり |
なし |
なし |
|
ありあり(5) |
なし |
なし |
なし |
|
あり |
あり脚注6 |
あり |
なし |
|
あり |
あり |
なし |
なし |
脚注4 スタンドアロンのストアド・プロシージャ、関数およびパブリック・パッケージ構成
脚注5
ロールに付与できない権限
脚注6
スナップショットに対しても付与可能
関連項目:
スキーマ・オブジェクトの監査方法の詳細は、オブジェクト・アクションの監査を参照してくださいアプリケーションの実装時およびテスト時には、必要な各ロールを作成する必要があります。
各ロールの使用例をテストし、データベースへのアクセス権がアプリケーション・ユーザーに正しく付与されることを確認します。テスト終了後は、アプリケーションの管理者と共同で各ユーザーに適切なロールが割り当てられていることを確認します。
表8-4に、表8-3で示したオブジェクト権限によって許可されるSQL文を示します。
表8-4 データベース・オブジェクト権限によって許可されるSQL文
| オブジェクト権限 | 許可されるSQL文 |
|---|---|
|
|
|
|
|
パブリック・パッケージ変数への参照 |
|
|
|
|
|
オブジェクト(表のみ)に対する |
|
順序を使用するSQL文 |
オブジェクト権限の詳細は、権限とロールの概要を参照してください。SQL文の監査方法の詳細は、オブジェクト・アクションの監査も参照してください。
プロトコル・エラーによる不正パケットの処理や認証エラーの上限の構成など、パラメータを使用してセキュリティを管理できます。
SEC_PROTOCOL_ERROR_TRACE_ACTION初期化パラメータで、プロトコル・エラーが発生したときにトレース・ファイルをどのように管理するかを制御します。
サーバーが不正なパケット、順序に誤りがあるパケット、プライベートまたは未使用のリモート・プロシージャ・コールを受信した場合、Oracle Call Interface(OCI)やTwo-Task Common(TTC)などのネットワーキング通信ユーティリティでは、スタック・トレースおよびヒープ・ダンプを格納する大規模なディスク・ファイルを生成できます。
通常、このディスク・ファイルは、非常に大規模になる可能性があります。侵入者は、サーバーに不正なパケットを繰り返し送信し、ディスクあふれやサービス拒否(DOS)攻撃を発生させることで、システムを使用できないようにする可能性があります。認証されていないクライアントが、この種の攻撃を仕掛ける可能性もあります。
これらの攻撃は、SEC_PROTOCOL_ERROR_TRACE_ACTION初期化パラメータを次の値のいずれかに設定することで防止できます。
None: サーバーが不正なパケットを無視し、トレース・ファイルまたはログ・メッセージを生成しないように構成します。サーバーの可用性が不正なパケットの受信を認識することよりも圧倒的に重要な場合は、この設定を使用します。
例:
SEC_PROTOCOL_ERROR_TRACE_ACTION = None
Trace(デフォルト設定): トレース・ファイルを作成します。これは、ネットワーク・クライアントが不具合の結果として不正なパケットを送信している場合など、デバッグを目的とする場合に便利です。
例:
SEC_PROTOCOL_ERROR_TRACE_ACTION = Trace
Log: サーバー・トレース・ファイルに1行の短いメッセージを書き込みます。この選択肢では、一定レベルの監査とシステムの可用性とのバランスがとれます。
例:
SEC_PROTOCOL_ERROR_TRACE_ACTION = Log
Alert: データベース管理者または監視コンソールにアラート・メッセージを送信します。
例:
SEC_PROTOCOL_ERROR_TRACE_ACTION = Alert
SEC_PROTOCOL_ERROR_FURTHER_ACTION初期化パラメータは、サーバーで不正パケットを受信した後のサーバー実行を制御します。
サーバーが悪意のあるクライアントから不正なパケットを受信しているときに、サーバー・プロセスの実行を詳細に制御するには、SEC_PROTOCOL_ERROR_FURTHER_ACTION初期化パラメータを次の値のいずれかに設定します。
Continue(デフォルト設定): サーバーの実行を継続します。ただし、サーバーがさらに攻撃を受ける可能性があることに注意してください。
例:
SEC_PROTOCOL_ERROR_FURTHER_ACTION = Continue
(Delay,m): クライアントをm秒間遅延させます(サーバーが次のリクエストを同じクライアント接続から受け付けるまで)。この設定により悪意のあるクライアントはサーバー・リソースを過剰使用できなくなります。正当なクライアントのパフォーマンスも低下しますが、引き続き機能します。この設定を入力する場合は、カッコで囲みます。
例:
SEC_PROTOCOL_ERROR_FURTHER_ACTION = (Delay,3)
ALTER SYSTEMまたはALTER SESSION SQL文を使用してSEC_PROTOCOL_ERROR_FURTHER_ACTIONを設定している場合は、Delay設定を一重引用符または二重引用符で囲む必要があります。
ALTER SYSTEM SEC_PROTOCOL_ERROR_FURTHER_ACTION = '(Delay,3)';
(Drop,n): クライアント接続は、n個の不正パケットを受信した後に強制的に終了します。この設定を使用すると、トランザクションの損失など、クライアントを犠牲にしてサーバー自体を保護できます。ただし、クライアントは再度接続して、同じ操作を再試行できます。この設定はカッコで囲みます。
例:
SEC_PROTOCOL_ERROR_FURTHER_ACTION = (Drop,10)
Delay設定と同様に、ALTER SYSTEMまたはALTER SESSIONを使用してこの設定を変更している場合は、Drop設定を一重引用符または二重引用符で囲む必要があります。
SEC_MAX_FAILED_LOGIN_ATTEMPTS初期化パラメータに設定された認証試行回数を超過すると、確立できなかった接続がデータベースで削除されます。
Oracle Databaseでは、サーバー・プロセスが最初に起動し、次にクライアントがこのサーバー・プロセスで認証を受けます。侵入者は、最初にサーバー・プロセスを起動し、様々なユーザー名とパスワードを使用して認証リクエストを無制限に発行し、データベースへのアクセスを試みます。
アプリケーション接続に対するログイン失敗回数を制限するには、SEC_MAX_FAILED_LOGIN_ATTEMPTS初期化パラメータを設定して、接続に対する認証試行回数を制限します。指定した認証試行回数を失敗すると、データベース・プロセスは接続を切断します。デフォルトでは、SEC_MAX_FAILED_LOGIN_ATTEMPTSは10に設定されます。
SEC_MAX_FAILED_LOGIN_ATTEMPTS初期化パラメータは、潜在的侵入者がアプリケーションを攻撃できないようにするためのものであることに注意してください。正当なユーザーには適用しません。sqlnet.ora INBOUND_CONNECT_TIMEOUTパラメータとFAILED_LOGIN_ATTEMPTS初期化パラメータもログイン失敗を制限しますが、違いはこの2つのパラメータが正当なユーザー・アカウントにのみ適用するということです。
たとえば、最大試行回数を5に制限するには、initsid.ora初期化パラメータ・ファイルで、次のようにSEC_MAX_FAILED_LOGIN_ATTEMPTSを設定します。
SEC_MAX_FAILED_LOGIN_ATTEMPTS = 5
クライアント接続(Oracle Call Interfaceクライアントを含む)が認証されてから、詳細な製品バージョン情報にアクセスできるようにする必要があります。
侵入者は、データベース・バージョンを使用して、データベース・ソフトウェアに存在するセキュリティの脆弱性に関する情報を検出する可能性があります。
認証されていないクライアントに対してデータベース・バージョン・バナーの表示を制限するには、initsid.ora初期化パラメータ・ファイルでSEC_RETURN_SERVER_RELEASE_BANNER初期化パラメータをTRUEまたはFALSEのいずれかに設定します。
デフォルトでは、SEC_RETURN_SERVER_RELEASE_BANNERはFALSEに設定されます。
たとえば、TRUEに設定すると、Oracle Databaseに正確なデータベース・バージョンが表示されます。この例ではリリース12.1.0.0です。
Oracle Database 12c Enterprise Edition Release 12.1.0.0 - Production
今後、たとえばOracle Databaseリリース12.2.0.2をインストールした場合は、次のバナーが表示されます。
Oracle Database 12c Enterprise Edition Release 12.2.0.2 - Production
ただし、同じリリースでこのパラメータをNOに設定すると、このバナーは制限されて、リリース12.2で開始する次の固定テキストが表示されるため、12.2.0.2ではなく12.2.0.0.0と表示されます。
Oracle Database 12c Release 12.2.0.0.0 - Production
SEC_USER_UNAUTHORIZED_ACCESS_BANNERおよびSEC_USER_AUDIT_ACTION_BANNER初期化パラメータで、不正アクセスやユーザーの監査に関するバナーの表示を制御します。
不正なアクセスおよびユーザー・アクション監査をユーザーに警告するには、バナーを作成して構成する必要があります。この通知は、クライアント・アプリケーションがデータベースにログインすると使用可能になります。
これらのバナーを構成して表示するには、データベース・サーバー側で次のsqlnet.oraパラメータを設定して、バナー情報が含まれるテキスト・ファイルを指し示します。
SEC_USER_UNAUTHORIZED_ACCESS_BANNER。次に例を示します。
SEC_USER_UNAUTHORIZED_ACCESS_BANNER = /opt/Oracle/12c/dbs/unauthaccess.txt
SEC_USER_AUDIT_ACTION_BANNER。次に例を示します。
SEC_USER_AUDIT_ACTION_BANNER = /opt/Oracle/12c/dbs/auditactions.txt
デフォルトでは、これらのパラメータは設定されません。さらに、バナー・テキストに使用される文字数には512バイトの制限があることを注意してください。
これらのパラメータを設定したら、これらのバナーを取得してエンドユーザーに表示するように、Oracle Call Interfaceアプリケーションで適切なOCI APIを使用する必要があります。