20.2.3 クロスサイト・スクリプティング保護の理解

クロスサイト・スクリプティング・セキュリティ攻撃からアプリケーションを保護します。

20.2.3.1 クロスサイト・スクリプティング・セキュリティ攻撃の概要

クロスサイト・スクリプティング(XSS)は、動的に生成されるWebページを利用するセキュリティ攻撃です。XSS攻撃では、ユーザーのブラウザに読み込まれたときにアクティブになるスクリプトがWebアプリケーションに送信されます。これらのスクリプトがアクティブになると、データまたは場合によってはセッション資格証明が盗まれ、それらの情報が攻撃者に送信される可能性があります。

悪意のあるコードがOracle Application Expressアプリケーションに侵入すると、通常のページ・レンダリング時に、そのコードがアプリケーション内のHTMLリージョンや他の場所にレンダリングされる可能性があります。セッション・ステートへの不正なコードの挿入を阻止するため、Application Expressエンジンは特定の場合に文字をエスケープします。

20.2.3.2 HTMLリージョンなどの静的領域の保護

HTMLリージョンなどの静的表示領域を保護する方法について学習します。

20.2.3.2.1 HTMLリージョンなどの静的領域の保護について

HTMLリージョンなどの静的領域では、置換文字列を使用してセッション・ステートを参照できます。テンプレート内で使用可能な特別な置換文字列は、シャープ記号(#)で示します(例: #ABC#)。ページまたはアプリケーション・アイテムを参照するには、&ITEM.表記法を使用します。

静的表示領域の例には、HTMLリージョン、ページのヘッダーとフッター、リージョンのヘッダーとフッター、リージョン・タイトル、ボタン・ラベル、ヘルプ・テキスト、フォーム・アイテム・ラベルおよび要素の後のテキスト、テンプレート、(フィールド・テキストの前後の)ラジオ・グループ、イベント成功メッセージ、イベント・エラー・メッセージ、ナビゲーション・バー属性、アプリケーション静的置換文字列値、チャート・ラベルおよび凡例、ブレッドクラムおよびリスト・フレーム・テキスト、カレンダ・テキスト、ラベル、凡例などがあります。

開発者は、感嘆符(!)の後に事前定義済のフィルタ名を続けたものをページまたはアプリケーション・アイテム名、あるいはレポート列参照に追加して、置換値内の特殊文字をエスケープできます。

20.2.3.2.2 安全なアイテム表示タイプについて

セッション・ステートがこのように参照される場合、ページに表示される値には、参照されるアイテムが「表示のみ」「セッション・ステートの保存」属性が「いいえ」、および特殊をエスケープ「いいえ」に設定されている場合にエスケープされる特殊文字(<>&")が含まれません。

参照されるアイテムに「セッション・ステートの保存」属性が「いいえ」に設定されている「表示のみ」以外の表示タイプが含まれている場合、ページに表示される値には、エスケープされる特殊文字が含まれます。また、アプリケーション・レベルのアイテムには、安全な表示タイプが含まれているとみなされますが、実際にフォーム・アイテムに含まれているような表示プロパティは含まれていません。

20.2.3.2.3 値をエスケープするかどうかを決定するために使用されるルールについて

Application Expressエンジンは、事前定義済のスマート・エスケープ・ルールを使用して、セッション・ステートからフェッチされた値をエスケープするかどうか、およびいつそれを実行するかを決定します。

このルールを使用するのは、前にリストした表示タイプを使用したアイテムは、通常フィルタ処理(エスケープ)されずにブラウザに表示されることを意図したHTMLを含むテキスト用であるためです。安全に行われる方法は、これらのタイプのアイテムが常にエスケープされてアプリケーションに入力されるルールを実施する以外にありません。たとえば、ユーザーが、Oracle Application Expressのf?p URL構文を使用して、一部のテキストを安全なアイテムに渡す場合、Application Expressエンジンは値をセッション・ステートに保存する際に特殊文字をエスケープします。これにより次の2つの結果が予想されます。

  1. 値に特殊文字が含まれていなかった場合、渡された値は指定されたとおりにセッション・ステートに保存される。

  2. 値に特殊文字が含まれていた場合、値をセッション・ステートに保存する際に特殊文字をエスケープする。

いずれの状況でも、アイテムは、現在、前述のHTMLリージョンなどの静的領域で&ITEM.表記法を使用して安全に参照できます。

20.2.3.2.4 安全なアイテム・タイプを使用したHTMLマークアップの保持および表示について

前にリストした安全なアイテム・タイプを使用して、ブラウザにHTMLマークアップを保持および表示します。たとえば、安全なページ・アイテムP1_XXX(&P1_XXXを使用)を参照して、太字で一部のテキストをレンダリングする要件があるとします。アイテムP1_XXXには次のHTMLが含まれているとします。

<b>ABABABAB</b>

実行するには、アプリケーション・コントロール(計算、プロセス、アイテムのソース式、アイテムのデフォルト値など)を使用して、値をこれらの安全なアイテムに格納します。値をこのように挿入する場合は、コンテンツの安全性を確認します。これらの方法を使用する場合、Application Expressエンジンは、値をセッション・ステートに保存する際に特殊文字をエスケープしません。

安全なアイテムの安全性は、最終的に、アイテムがページにポストされず、ページ送信の一部としてApplication Expressエンジンに発行されないルールによって確認されます。

20.2.3.3 動的出力の保護について

htp.pなどの方法を使用してセッション・ステートからフェッチし、レンダリングするアイテムは、必要に応じてコードで明示的にエスケープする必要があります。たとえば、ページ上のPL/SQL動的コンテンツ・リージョンで次を使用するとします。

htp.p(v('SOME_ITEM'));

セッション・ステートからフェッチするアイテムの値に予期しないタグやスクリプトが含まれる可能性がある場合は、リージョンで次を使用できます。

htp.p(apex_escape.html(:SOME_ITEM));

ただし、フェッチする値を安全にレンダリングできることが確かな場合は、この値をエスケープする必要はありません。開発者は、出力をエスケープしない方が適切な場合を判断する必要があります。

次のように、このルールに従うことをお薦めします。

  • アイテムが安全なタイプでないかぎり、エスケープせずにセッション・ステートからフェッチされたアイテムを表示しないでください。

これを行うのは、開発者としてハッカーが悪意ある値を安全ではないアイテムにポストするのを防ぐ方法はないためです。アプリケーションがこれらのアイテムを一般ユーザーに見えるように表示しなくても、このルールに従わないと、ハッカーはアプリケーションを使用してXSS攻撃をマウントできることに注意してください。

20.2.3.4 レポート・リージョンの保護について

Application Expressエンジンは、レポートのボディでレンダリングされるデータをエスケープします。レポートのヘッダーおよびメッセージにおけるセッション・ステートへの参照は、安全なアイテム・タイプの値はエスケープされず、その他のアイテム・タイプの値はエスケープされるように、スマート・エスケープ・ルールを使用してセッション・ステートからフェッチされます。

Oracle Application Expressでは、列の「特殊文字をエスケープ」属性が「オン」に設定されている場合、レポート列のHTML特殊文字が自動的にエスケープされます。プレーン列値のかわりにHTMLフラグメントをレンダリングする必要がある場合(たとえば、ハイライトのために)、(「特殊文字をエスケープ」の使用を妨げる)問合せ自体でのHTMLフラグメントの連結を行わずに、レポート列の「HTML式」属性を使用する必要があります。「HTML式」属性で、静的HTMLを入力し、#COLUMN#表記法を使用してエスケープされた列値を埋め込むことができます。拡張された列表記法により、Oracle Application Expressが列値をエスケープする方法を制御できます。

  • #COLUMN!HTML# - 予約済のHTML文字をエスケープします。

  • #COLUMN!ATTR# - HTML属性のコンテキストで予約済の文字をエスケープします。

  • #COLUMN!JS# - JavaScriptのコンテキストで予約済の文字をエスケープします。

  • #COLUMN!RAW# - 元のアイテム値を保持し、文字をエスケープしません。

  • #COLUMN!STRIPHTML# - HTMLタグを出力から削除し、予約済のHTML文字をエスケープします。

たとえば、次の問合せに基づくレポートがあるとします。

SELECT
    empno,
    ename,
    NULL DELETE_LINK
FROM emp

この例では、すべての列がエスケープされます。「HTML式」をDELETE_LINKで次のように定義できます。

<a href="javascript:if (confirm('Do you really want to delete #ENAME!JS#?')) doSubmit('DELETE-#EMPNO#');">Delete</a>

この例では、従業員を削除するかどうかを確認するリンクがレンダリングされ、ユーザーが確認した場合は、行を削除するリクエストが送信されます。#ENAME!JS#ではなく#ENAME#を使用した場合、O'Neillのような名前は構文エラーの原因となり、攻撃者は不適切なエスケープをクロスサイト・スクリプティングに利用できます。

20.2.3.5 フォーム・アイテムの保護について

ブラウザに送信されるフォーム・ページの生成中に、フォーム・アイテム(隠しアイテムなど)が値を取得する場合、結果テキストはレンダリング前にエスケープされます。一部の安全なアイテム・タイプは、各表示タイプの意図する動作をサポートするため、このルールにおける例外となります。

一部のアイテム・タイプには、「特殊文字をエスケープ」セキュリティ属性があります。「特殊文字をエスケープ」属性を使用して、値をエスケープするかどうかを指定します。クロスサイト・スクリプティング(XSS)攻撃を防ぐには、この属性を常に「オン」に設定します。ページ・アイテムまたは値リストのエントリに格納されているHTMLタグをレンダリングする必要がある場合は、このフラグを「オフ」に設定できます。そのような場合は、該当するフィールドにユーザーが入力してから保存されるまでに入力内容が適切にエスケープされるように、追加の予防措置を講じる必要があります。

開発者は、感嘆符(!)の後に事前定義済のフィルタ名を続けたものをページまたはアプリケーション・アイテム名、あるいはレポート列参照に追加して、置換値内の特殊文字をエスケープできます。

20.2.3.6 アイテムに入力する文字の制限について

ユーザーがセッション・ステートに保存できる文字を制限することで、クロスサイト・スクリプティング(XSS)およびその他のインジェクション攻撃を制限できます。これを行うには、ページ・アイテムを編集して、「セキュリティ」「制限付き文字」属性を構成します。「制限付き文字」はセッション・ステートに保存できます。使用可能なオプションは次のとおりです。

  • すべての文字を許可

    制限は適用されません。

  • a-Z、0-9と空白のホワイトリスト

    文字a-z、A-Z、0-9および空白のみ許可されます。

  • ブラックリストHTMLコマンド文字(<>")

    予約済のHTML文字は許可されません。

  • ブラックリスト&<>"/;,*|=%および--

    &、<、>、"、/、;、","、*、|、=、%および"--" (PL/SQLコメント)は許可されません。

  • ブラックリスト&<>"/;,*|=%または--と改行

    &、<、>、"、/、;、","、*、|、=、%、"--"、および改行文字は許可されません。

制限を選択する場合、選択された文字制限に一致しないデータをユーザーが保存しようとすると、Oracle Application Expressからエラー・メッセージが表示されます。