セキュリティ保護された Web アプリケーションの設計ガイドライン
トピック
モジュールの内容
目的
適用対象
モジュールの使用方法
Web アプリケーションに関するアーキテクチャと設計上の問題
展開に関する考慮事項
入力検証
認証
承認
構成管理
機密性の高いデータ
セッション管理
暗号化
パラメータ操作
例外管理
監査とログ記録
設計ガイドラインのまとめ
要約
その他のリソース
モジュールの内容
Web アプリケーションは、設計者、デザイナ、開発者にとってセキュリティの問題が複雑に組み合わさっています。最も安全で攻撃に対する許容力の高い Web アプリケーションとは、最初からセキュリティを念頭に置いて作られたアプリケーションです。
構造上、および設計上安定した運用方法を適用し、展開項目と企業のセキュリティ ポリシーを設計の初期の段階で組み込む必要があります。これができないと、セキュリティを既存のインフラストラクチャに展開するときに、危険にさらすアプリケーションになってしまいます。
このモジュールでは、セキュリティで保護されたアーキテクチャと設計ガイドラインについて説明します。ここでは、一般的なアプリケーションの脆弱性をカテゴリ別に整理しています。これらは Web アプリケーションのセキュリティの鍵となる分野であり、最も誤解されやすい部分です。
目的
このモジュールの目的は次のとおりです。
-
セキュリティで保護された Web アプリケーションでの主な構造上、および設計上の問題について確認する。
-
設計時の主な展開問題について検討する。
-
Web アプリケーションの入力検証を改善するための戦略を設計する。
-
セキュリティで保護された認証およびセッション管理機構を設計する。
-
適切な承認モデルを選択する。
-
効果的なアカウント管理方法を実装し、ユーザー セッションを保護する。
-
暗号化を使用してプライバシー保護、否認防止、改ざん防止、および認証をする。
-
パラメータ操作を防止する。
-
監査およびログ記録戦略を設計する。
適用対象
このモジュールの内容は ASP.NET のセキュリティ関連マニュアルにも記載されていますが、セキュリティで保護された Web アプリケーションの開発に関心を持つ読者に適しています。
モジュールの使用方法
このモジュールでは、アプリケーションを設計する場合に準拠するガイドラインと原則について焦点を当てます。
モジュールの効果的な使用方法
-
アプリケーションの脅威について理解し、設計によって対処できるようにします。考慮する必要のある脅威について理解するには、モジュール 2「脅威とその対策」を参照してください。モジュール 2 には、アプリケーションに危害を与える可能性のある脅威について示されています。設計段階では、これらの脅威を考慮する必要があります。
-
アプリケーションの攻撃に対する脆弱性がある主な分野では、体系的に取り組みます。展開に関する考慮事項、入力検証、認証と承認、暗号化と機密度、構成、セッションと例外管理、および説明責任のための十分な監査とログ記録に焦点を当てます。
Web アプリケーションに関するアーキテクチャと設計上の問題
Web アプリケーションには、設計者と開発者にとって、多くの課題があります。ステートレスな性質を持つ HTTP に関してアプリケーションに重要なのは、ユーザーごとにセッション状態を追跡することです。その準備手続きとして、何らかの認証形式を使用してユーザーを識別できる必要があります。それ以降のすべての認証決定がユーザーの識別情報に基づく場合は、認証プロセスが安全であり、認証されたユーザーの追跡に使用されるセッション処理機構も同様に保護されていることが不可欠です。安全な認証機構とセッション管理機構の設計は、Web アプリケーション設計者と開発者が直面している問題です。入力データと出力データはパブリック ネットワーク上を通過するため、これ以外の課題も発生します。パラメータ操作と機密性の高いデータの漏えいを阻止することも、最大の課題です。
図 4.1 に、セキュリティで保護された設計方法で対処する必要のあるいくつかの重要課題を示します。

図 4.1
Web アプリケーションの設計課題
このモジュールの設計ガイドラインは、アプリケーションの脆弱性のカテゴリ別に構成されています。これらのカテゴリにおける設計が十分でないと、セキュリティの脆弱性につながることがわかっています。表 4.1 に、脆弱性のカテゴリと、間違った設計によって発生する可能性のある潜在的な問題の一覧を示します。
表 4.1: 間違った設計による Web アプリケーションの脆弱性と潜在的な問題
|
脆弱性のカテゴリ |
間違った設計による潜在的な問題 |
|---|---|
|
入力検証 |
クエリ文字列、フォーム フィールド、Cookie、HTTP ヘッダーに悪意のある文字列を組み込んで攻撃します。コマンド実行、クロスサイト スクリプティング (XSS)、SQL 挿入、バッファ オーバーフロー攻撃などがあります。 |
|
認証 |
なりすまし、パスワード解読、権限の不正取得、不正アクセスが行われます。 |
|
承認 |
機密データ、または制限されたデータへのアクセス、改ざん、許可されていない処理が実行されます。 |
|
構成管理 |
管理インターフェイスへの不正アクセス、構成データの更新機能、ユーザー アカウントとアカウント プロファイルへの不正アクセスが行われます。 |
|
機密性の高いデータ |
機密情報の漏えいとデータの改ざんが行われます。 |
|
セッション管理 |
セッションのハイジャックとなりすましを可能にするセッション識別子が取得されます。 |
|
暗号化 |
機密データかアカウント資格情報、またはその両方へアクセスされます。 |
|
パラメータ操作 |
パス トラバーサル攻撃、コマンド実行、中でもアクセス管理機構のバイパスによって、情報の漏えい、権限の不正取得、およびサービス拒否につながります。 |
|
例外管理 |
サービス拒否、機密性の高いシステム レベルの詳細データの漏えいがあります。 |
|
監査とログ記録 |
侵入の兆候を発見できないこと、ユーザー操作を証明できないこと、さらに障害診断の問題があります。 |
展開に関する考慮事項
アプリケーションの設計段階では、企業のセキュリティ ポリシーとセキュリティ手順について、アプリケーションを展開するインフラストラクチャと共に検討する必要があります。多くの場合、ターゲット環境は固定化されており、アプリケーション設計ではその制約を反映する必要があります。たとえば、プロトコルやポート制限、または固有の展開トポロジなどの理由から、設計上のトレードオフが必要な場合もあります。設計の初期段階で制約を識別することで、後で予想していなかった事態が起こることを回避します。また、ネットワーク チームとインフラストラクチャ チームのメンバも設計プロセスに協力します。
図 4.2 に設計時間を考慮する必要のあるさまざまな展開を示します。

図 4.2
展開に関する考慮事項
セキュリティ ポリシーと処理手順
セキュリティ ポリシーによって、アプリケーションが許可されている動作とアプリケーションのユーザーが許可されている動作が決定されます。さらに重要なのは、アプリケーションとユーザーの動作に制約を定義することで、許可されない動作を判断することです。アプリケーションの設計時は、企業のセキュリティ ポリシーによって定義されたフレームワークの中で識別と作業を行い、アプリケーションの展開を妨げるようなポリシーの違反がないことを確認します。
ネットワーク インフラストラクチャのコンポーネント
必ずターゲット環境によって実現されるネットワーク構造を理解し、フィルタ処理のルール、ポートの制限、対応プロトコルなどの面から、セキュリティ要件のベースラインについて理解します。
ファイアウォールとファイアウォール ポリシーがアプリケーションの設計と展開に及ぼす影響について確認します。ファイアウォールがインターネット対応のアプリケーションを内部ネットワークから切り離す場合もあります。データベースの正面にファイアウォールを追加する場合もあります。これらは通信ポート、Web サーバーからリモート アプリケーション、およびデータベース サーバーへの認証オプションにまで影響する可能性があります。たとえば、Windows® の認証では追加ポートが必要です。
設計段階では、境界領域ネットワークの Web サーバーから内部リソースへのアクセスを許可するプロトコル、ポート、サービスを何にするか検討します。さらに、アプリケーション設計で必要なプロトコルとポートを確認し、新しいポートを開いたり、新しいプロトコルを使用することで発生する潜在的な脅威を分析します。
ネットワーク層とアプリケーション層のセキュリティに関する仮定と、どのコンポーネントで何を処理するのかについて話し合った結果を記録します。これによって、開発チームとネットワーク チームのどちらが問題に対処するのか明確になり、セキュリティ制御のミスを防ぐことができます。アプリケーションがネットワークに依存している部分のセキュリティの防御について注意が必要です。ネットワーク構成の変更による影響を考慮します。つまり、特定のネットワークの変更を実装した場合、どの程度のセキュリティが失われるかということです。
展開トポロジ
アプリケーションの展開トポロジとリモート アプリケーション層を持っているかどうかについては、設計に組み込む必要のある重要な検討事項です。リモート アプリケーション層がある場合は、ネットワーク盗聴の脅威に対処し、機密性の高いデータのプライバシーと完全性を提供するために、サーバー間のネットワークをセキュリティで保護する方法について検討する必要があります。
さらに、識別情報のフローを考慮し、アプリケーションがリモート サーバーに接続したときにネットワーク認証に使用されるアカウントを識別します。共通する方法は、最小限の権限を持つプロセス アカウントを使用して、リモート サーバー上で同じパスワードを使用して二重化した (ミラーリング) アカウントを作成することです。または、ドメイン プロセス アカウントを使用することもできます。ただし、この方法を使用すると管理は容易になりますが、ネットワーク全体を通じてアカウントの使用を制限することが困難なため、セキュリティの保護の問題が発生しやすくなります。多くの場合、介在性のファイアウォールまたは信頼関係のない別々のドメインを使用したローカル アカウント方法が実現可能な唯一のオプションになります。
イントラネット、エクストラネット、インターネット
イントラネット、エクストラネット、インターネット アプリケーションの場合、いずれも設計上の課題があります。検討課題には、次のものがあります。呼び出し元の識別情報は複数のアプリケーション層を経由してバックエンド リソース側にフローするか。どこで認証を実行するか。フロント エンドでの認証を信頼し、信頼関係接続を使用してバックエンド リソースにアクセスできるか。エクストラネットの場合には、相手側のアカウントを信頼するかどうかも検討する必要があります。
これらの問題、およびその他の固有の問題については MSDN の「セキュリティ保護された ASP.NET アプリケーションの構築」(http://www.microsoft.com/japan/msdn/net/security/secnetlpMSDN.aspx) の「第 5 章 イントラネット セキュリティ」、「第 6 章 エクストラネット セキュリティ」、および「第 7 章 インターネット セキュリティ」のセクションを参照してください。
入力検証
入力検証は困難な問題であり、その解決はアプリケーション開発者に課せられた主要な任務になっています。ただし、入力検証を適切に行うと、今日のアプリケーション攻撃に対抗する最強の防御策の 1 つとなります。入力検証を適切に行うことで、効果的に対処でき、XSS、SQL 挿入、バッファ オーバーフローなどの入力攻撃を阻止することができます。
アプリケーション全体、またはアプリケーション内部で何が有効な入力なのか、答えが 1 つではないために、入力検証が困難になります。同様に、悪意のある入力についての定義も存在しません。このような問題をさらに困難にしているのが、アプリケーションで入力を処理する目的によって悪用されるリスクに影響することです。たとえば、別のアプリケーションで使用するデータを格納するのか、別のアプリケーションで作成したデータ ソースからの入力を使用するのか、などです。
次の方法を使用すると、Web アプリケーションの入力検証を改善できます。
-
すべての入力が悪意のあるものと仮定します。
-
アプローチを集中化します。
-
クライアント側の検証に依存しません。
-
正規化の問題に注意します。
-
入力を制限、拒否、および校正します。
すべての入力が悪意のあるものと仮定する
入力検証では、基本的にすべての入力は、安全であることが証明されるまでは、悪質なものであると仮定することから始めます。発信元が信頼境界の外部からのものであれば、サービス、ファイル共有、ユーザー、またはデータベースからの入力かどうかにかかわらず、入力を検証します。たとえば、文字列を返す外部の Web サービスを呼び出す場合、悪意のあるコマンドが存在しないことをどのようにして知ることができるか、複数のアプリケーションが共有データベースに書き込む場合、読み込んだデータが安全かどうかを知るにはどうしたらよいか、などです。
アプローチを集中化する
入力検証方針をアプリケーション設計の中心的要素にします。検証アプローチを集中化することを検討します。たとえば、共有ライブラリの共通の検証コードとフィルタ コードを使用します。これによって、入力規則を一貫して適用できます。さらに、開発作業を軽減し、将来の保守にも役立ちます。
多くの場合、個々のフィールドについて、たとえば特別に開発された正規表現を使用するなどの固有の検証が必要です。ただし、共通のルーチンを解釈して、電子メール アドレス、件名、名前、郵便番号を含む住所など、正規に使用されるフィールドの検証が頻繁にできます。図 4.3 に、このアプローチを示します。

図 4.3
集中化したアプローチによる入力検証
クライアント側の検証に依存しない
サーバー側はサーバー自体のコードで独自に検証する必要があります。攻撃者がクライアントを超えてアクセスしたり、たとえば、JavaScript を無効することによってクライアント側のスクリプト ルーチンを遮断した場合にはどうなるか、などです。クライアント側の検証を使用してサーバーへのラウンド トリップの回数を減らし、セキュリティをクライアント側に依存しないようにします。これは、多層防御の一例です。
正規化問題に注意する
正規の形式のデータは、最も標準的、つまり単純な形式です。正規化とは、データを正規の形式に変換する処理です。ファイル パスと URL は特に正規化が問題になりやすく、よく知られている悪用の多くは正規化のバグに直接起因しています。たとえば、正規の形式で表現されたファイルとパスを含む次の文字列について検討します。
c:\temp\somefile.dat
次の文字列も同じファイルを表しています。
somefile.dat c:\temp\subdir\..\somefile.dat c:\ temp\ somefile.dat ..\somefile.dat c%3A%5Ctemp%5Csubdir%5C%2E%2E%5Csomefile.dat
最後の例では、文字が 16 進形式で指定されています。
-
%3A はコロンです。
-
%5C はバックスラッシュです。
-
%2E はピリオドです。
通常、正規化の問題を回避するため、ユーザーからのファイル名の入力を受け付けないようにアプリケーションを設計します。代わりに、別の設計を検討します。たとえば、ユーザーに代わって、アプリケーションがファイル名を決定できるようにします。
入力したファイル名を受け付ける必要がある場合は、指定されたファイルへのアクセス許可を与えるか、拒否するかなどのセキュリティの決定をする前に、それらが厳密に形式化されていることを確認します。
ファイル名の処理方法、および安全なファイル入出力方法の詳細については、モジュール 7「セキュリティ保護されたアセンブリを構築する」の「ファイル I/O」、およびモジュール 8「コード アクセス セキュリティの実践」を参照してください。
入力を制限、拒否、校正する
推奨される入力検証方法では、最初から許可する対象を制限します。既知の不正な文字を検索することによってデータを検証するよりも、既知の有効なタイプ、パターン、範囲のデータを検証する方が簡単です。アプリケーションを設計する場合、アプリケーションで何が必要なのかを把握します。通常、有効なデータ範囲は、潜在的に悪意のある入力よりも限定されています。ただし、多層防御の場合は、既知の不正な入力を拒否し、入力を校正する必要がある場合もあります。図 4.4 に、推奨される計画を示します。

図 4.4
入力検証計画: 入力を制限、拒否、校正する
効果的な入力検証計画を作成するには、次のアプローチとトレードオフを認識する必要があります。
-
入力を制限します。
-
データのタイプ、長さ、形式、および範囲を検証します。
-
既知の不正な入力を拒否します。
-
入力を校正します。
入力を制限する
入力の制限とは、正しいデータを許可することです。これは、推奨されるアプローチです。この考え方は、タイプ、長さ、形式、範囲を使用して、許容可能な入力のフィルタを定義することです。アプリケーション フィールドに許容可能な入力を定義して、それを適用します。他のすべての不正なデータを拒否します。
入力を制限する場合は、ローカライズされた方法で正規の入力形式を確立できるようにするために、サーバー上での文字セットの設定が必要です。
データのタイプ、長さ、形式、および範囲を検証する
たとえば、入力データの操作と処理に使用されるクラス内、およびデータ アクセス ルーチン内ではできるだけ、入力データを強力にチェックするタイプを使用します。たとえば、データ アクセスにパラメータ化されたストアド プロシージャを使用することで、入力フィールドを強力にチェックするタイプが利用できます。
文字列フィールドは、長さもチェックする必要があり、また多くの場合、適切な形式になっていることをチェックする必要があります。たとえば、郵便番号、個人の識別情報番号などは、正規表現によって検証可能な適切に定義された形式です。徹底的なチェックは、プログラミング手法として正しいだけでなく、攻撃者によるコードの悪用をより困難にします。攻撃者は、タイプのチェックを通り抜ける可能性がありますが、長さのチェックによって攻撃がより困難になります。
既知の不正な入力を拒否する
"不正な" データを拒否します。ただし、このアプローチに完全に依存することはできません。通常、この方法は、前の "許可" アプローチを使用する場合よりも効果は低くなりますが、最善の方法はこれらを組み合わせて使用することです。不正なデータを拒否するには、悪意のある入力のさまざまなバリエーションをアプリケーションで把握できることが前提となります。文字を表現するには、複数の方法があることを知っておく必要があります。これは、"許可" が推奨されるもう 1 つの理由です。
"拒否" アプローチは、既に展開されているアプリケーションが対象となる場合、また、大がかりに変更する余裕がない場合に有用ですが、"許可" アプローチほど強力ではありません。不正なデータ、たとえば共通の攻撃を識別できるパターンなどは、常に一定ではないためです。不正なデータ範囲が時間の経過とともに変化するのに対し、有効なデータは常に一定です。
入力を校正する
データの校正とは、潜在的に悪意のあるデータを安全にすることです。許可された入力範囲で、入力が安全なことが保証できない場合に役立ちます。これには、ユーザー指定文字列の最後の NULL 値をストリッピングすることから、リテラルとして扱われるように値をエスケープすることまで、一連の処理が含まれます。
Web アプリケーションにおける入力の校正を示すもう一つの一般的な例は、URL エンコード、または HTML エンコードを使用してデータを折り返したり、実行形式のスクリプトではなく文字列として扱うことです。HtmlEncode メソッドは HTML 文字をエスケープし、UrlEncode メソッドは URL をエンコードして、有効な URI 要求にします。
演習
次に、前のアプローチを使用して、共通の入力フィールドに適用した場合の例を示します。
-
名前フィールド: 入力の制約が適切な場合の例です。この場合、ASCII の AZ および az の範囲内の文字列データを許可します。さらに、ハイフン、カーリー アポストロフィ (カーリー アポストロフィは SQL に対して意味を持たない) は O'Dell などの名前を扱う場合に許可します。さらに、予期される最も長い値に長さを制限します。
-
数量フィールド: これは、入力の制限がうまく動作するもう 1 つの例です。この例では、単純なタイプと範囲制限を使用できます。たとえば、入力データは 0 から 100 までの正の整数である必要があります。
-
フリーテキスト フィールド: 例として、ディスカッション掲示板のコメント フィールドがあります。この場合、文字、スペース、さらにアポストロフィ、コンマ、ハイフンなどの共通の文字を許可することができます。許可される文字セットには、不等号 (大なり、小なり)、大かっこ、中かっこは含まれません。
一部のアプリケーションでは、太字 "<b>"、斜体 "<i>" などの限定されたスクリプト文字セットを使用してテキストを強調したり、お気に入りの URL のリンクを入れることができます。URL の場合、検証では値が URL として扱われるようにエンコードする必要があります。
フリーテキスト フィールド検証の詳細については、モジュール 10「セキュリティ保護された ASP.NET ページとコントロールを構築する」の「入力検証」を参照してください。
-
ユーザー入力を検証しない既存の Web アプリケーション: 理想的な手法では、アプリケーションが各フィールド、またはエントリ ポイントについて使用可能な入力を確認します。ただし、ユーザー入力を検証しない既存の Web アプリケーションの場合は、アプリケーションの入力検証計画を改善できるまで、暫定的な手法でリスクを緩和する必要があります。次のアプローチは、入力の発信元とアプリケーション内での使用法に依存するため、いずれも安全な入力処理が保証されませんが、実際には、短期的にセキュリティを向上するための応急措置となっています。
-
クライアントへのライト バック時のユーザー入力の HTML エンコードと URL エンコード: この場合、入力は HTML として扱われることなく、すべての出力が保護された形式でライト バックされることが前提となります。これは、実際に使用されている校正方法です。
-
悪意のあるスクリプト文字を拒否する: これは、既知の不正な入力を拒否する場合です。この場合、入力を拒否するために、構成可能な悪意のある文字セットが使用されます。前のとおり、このアプローチの問題点は、不正なデータの問題がコンテキストにあることです。
-
入力コーディング、正規表現の使用法、ASP.NET 検証制御の詳細については、モジュール 10「セキュリティ保護された ASP.NET ページとコントロールを構築する」の「入力検証」を参照してください。
認証
認証とは、呼び出し元の識別情報を特定する処理のことです。次の 3 つの側面から検討します。
-
アプリケーション内で認証が必要な場所を識別します。通常、信頼境界が交差している場合には必要です。信頼境界には、通常、アセンブリ、プロセス、ホストが含まれます。
-
呼び出し元を検証します。通常、ユーザーは、ユーザー名とパスワードでユーザー認証を行います。
-
それ以降の要求でユーザーを識別します。これには、ある形態の認証トークンが必要です。
多くの Web アプリケーションは、パスワード機構を使用してユーザー認証を行いますが、この場合、ユーザーはユーザー名とパスワードを HTML 形式で示します。ここでの検討課題と問題点には次のものがあります。
-
ユーザー名とパスワードはセキュリティで保護されていないチャネル上でプレーンテキストとして送信されるか: その場合は、攻撃者がネットワーク監視ソフトウェアを使用して盗聴し、資格情報を攻略することが可能です。この対応策として、Secure Sockets Layer (SSL) を使用して、通信チャネルをセキュリティで保護する方法があります。
-
資格情報をどのように保存するか: ユーザー名とパスワードをファイルまたはデータベースのいずれかにプレーンテキストで格納すると、問題が生じます。アプリケーション ディレクトリが適切に構成されずに、攻撃者がファイルを参照し、その内容をダウンロードしたり、新たに権限を持つログオン アカウントを追加した場合はどうなるか。不満を持った管理者がユーザー名とパスワードのデータベースを持ち出した場合はどうなるか。
-
資格情報をどのように検証するか: ユーザーがパスワードを知っているかどうかを検証することが唯一の目的だとすれば、ユーザーのパスワードを保存する必要はありません。代わりに、ハッシュ値の形式で検証を保存し、ログオン プロセス時にユーザー指定の値を使用してハッシュを再計算できます。資格情報ストアに対する辞書攻撃の脅威を緩和するには、強力なパスワードを使用し、ランダムに生成された Salt 値とパスワード ハッシュを結合します。
-
最初のログオン後に認証ユーザーはどのように識別されるか: 何らかの形態の認証チケット、たとえば、認証 Cookie などが必要です。Cookie のセキュリティは、どのように保護されるか。セキュリティで保護されていないチャネル上で送信された場合、攻撃者が Cookie を獲得して、それを使用し、アプリケーションにアクセスする可能性があります。盗難された認証 Cookie は盗難されたログオンと同じです。
次の方法を使用すると、Web アプリケーションの認証を改善できます。
-
公共エリアと制限エリアを区別します。
-
エンド ユーザー アカウントに対してアカウント ロックアウトのポリシーを使用します。
-
パスワード有効期限をサポートします。
-
アカウントを無効にすることができます。
-
パスワードをユーザー ストアに保存しません。
-
強力なパスワードを要求します。
-
ケーブル上でプレーンテキストのパスワードを送信しないでください。
-
認証 Cookie を保護します。
公共エリアと制限エリアを区別する
サイトの公共エリアには、ユーザーは匿名でアクセスできます。制限エリアには、特定の個人だけがアクセスでき、ユーザーはそのサイトを使用して認証される必要があります。代表的な小売 Web サイトについて検討してみます。製品カタログは匿名で参照できます。ショッピング カートに商品を追加すると、アプリケーションはセッション識別子でユーザーを識別します。最後に、発注を行うと、セキュリティで保護されたトランザクションを実行します。この場合、ユーザーはログインすることによって SSL 上のトランザクションを認証する必要があります。
サイトを公共エリアと制限エリアに分割することによって、別々の認証と認証規則をサイト全体に適用し、SSL の使用を制限することができます。SSL に関連する不要なパフォーマンスの低下を回避するため、認証アクセスが必要な領域に SSL の使用を限定するようにサイトを設計します。
エンド ユーザー アカウントに対してアカウント ロックアウトのポリシーを使用する
エンド ユーザー アカウントを無効にするか、一定の回数以上ログオンに失敗した場合、イベントをログに記録します。NTLM または Kerberos プロトコルなどの Windows 認証を使用する場合、オペレーティング システムによって自動的にこれらのポリシーを構成し、設定することが可能です。フォーム認証を使用する場合、これらのポリシーはアプリケーションで実行され、アプリケーション設計に組み込む必要があります。
アカウント ロックアウトのポリシーは、サービス拒否 (DoS) 攻撃で不正使用できないことに注意してください。たとえば、IUSR_MACHINENAME などの有名な既定のサービス アカウントは、Internet Information Services (IIS) Web サーバー名を獲得した攻撃者がこの重要なアカウントをロックアウトすることを阻止するために、カスタム アカウント名で置き換える必要があります。
パスワード有効期限をサポートする
パスワードは静的にせず、パスワード有効期限を利用し、パスワード保守の一部として定期的に変更する必要があります。アプリケーション設計時には、このタイプのサービスを提供することを検討します。
アカウントを無効にできる
システムが危険にさらされた場合、資格情報、またはアカウントを故意に無効にする機能によって、新たな攻撃を阻止することができます。
パスワードをユーザー ストアに保存しない
パスワードを検証する必要がある場合、パスワードを実際に保存する必要はありません。代わりに、一方向のハッシュ値を格納し、ユーザーが指定したパスワードを使用してハッシュを再計算します。ユーザー ストアに対する辞書攻撃の脅威を緩和するには、強力なパスワードを使用し、ランダムな Salt 値をパスワードに組み込みます。
強力なパスワードを要求する
攻撃者が簡単にパスワードを解読できないようにします。多くのガイドラインを使用できますが、一般的な方法では、大文字と小文字、数字、特殊文字を含む 8 文字以上を指定する必要があります。これらのガイドラインを適用するプラットフォームを使用する場合、または独自の検証方法を作成する場合、強力なパスワードを要求することで、システム テストやエラーを利用して攻撃者がパスワードを解読するブルート フォース攻撃に対抗できます。正規表現を使用すると、強力なパスワード検証に役立ちます。
たとえば、パスワード検証を支援する正規表現の例については、モジュール 10「セキュリティ保護された ASP.NET ページとコントロールを構築する」の「入力検証」を参照してください。
ケーブル上でプレーンテキストのパスワードを送信しない
ネットワーク上で送信されるプレーンテキスト パスワードは、盗聴に対する脆弱性があります。この脅威に対処するには、たとえば、SSL を使用してトラフィックを暗号化することによって通信チャネルをセキュリティで保護します。
認証 Cookie を保護する
盗難された認証 Cookie は盗難されたログオンと同じです。認証チケットを保護するには、暗号化とセキュリティで保護された通信チャネルを使用します。さらに、認証チケットの有効期間を制限し、攻撃者が Cookie を取り込み、それを使用してサイトに不正にアクセスするリプレイ攻撃によるなりすまし攻撃に対抗します。Cookie のタイムアウト時間を短縮しても、リプレイ攻撃を防止することにはなりませんが、盗難した Cookie を使用して攻撃者がサイトにアクセスする時間を制限することはできます。
承認
承認は、認証された識別情報が実行できる動作とアクセス可能なリソースを決定します。認証が不適切、または安易な場合は、情報の漏えいとデータの改ざんの原因となります。多層防御は、アプリケーションの承認戦略に適用するための主要なセキュリティ原則です。
次の方法を使用すると、Web アプリケーションの認証を改善できます。
-
複数のゲートキーパーを使用します。
-
ユーザー アクセスをシステム レベルのリソースに限定します。
-
承認レベルの粒度について検討します。
複数のゲートキーパーを使用する
サーバー側では、Internet Protocol Security (IPSec) ポリシーを使用して、ホスト制限を設定し、サーバー間通信を制限することが可能です。たとえば、IPSec ポリシーは、指定された Web サーバー以外のホストがデータベース サーバーに接続することを制限できます。IIS は、Web アクセス許可と Internet Protocol/Domain Name System (IP/DNS) 制限を提供します。IIS Web アクセス許可は、ユーザーに関係なく、HTTP 上で要求されたすべてのリソースに適用されます。攻撃者がサーバーにログオンした場合は保護できません。このような場合には、NTFS 許可によって、ユーザー別のアクセス制御リストを指定できます。最後に、ASP.NET は URL 承認とファイル承認を主要な許可要求と併せて提供しています。以上のゲートキーパーを結合することで、効果的な承認戦略を開発できます。
ユーザー アクセスをシステム レベルのリソースに限定する
システム レベルのリソースには、ファイル、フォルダ、レジストリ キー、アクティブ ディレクトリ オブジェクト、データベース オブジェクト、イベント ログなどが含まれます。どのユーザーがどのリソースにアクセスできるかを制限したり、ユーザーが実行できる処理を制限するには、Windows のアクセス制御リスト (ACL) を使用します。匿名のインターネット ユーザー アカウントには特別の注意を払う必要があります。リソース上で匿名ユーザーからのアクセスを明示的に拒否する ACL を使用して、これらのアカウントをロックします。
Windows の ACL を使用して匿名のインターネット ユーザー アカウントをロックする方法の詳細については、モジュール 16「Web サーバーをセキュリティ保護する」を参照してください。
承認レベルの粒度を検討する
一般的には、粒度のレベルと拡張性が異なる 3 つの承認モデルがあります。
最も粒度の高いアプローチは、偽装を利用します。リソース アクセスは、呼び出し元のセキュリティ コンテキストを使用することで発生します。セキュリティで保護されたリソース (通常、ファイル、テーブル、またはその両方) 上の Windows ACL によって、呼び出し元がリソースにアクセスすることを許可するかどうかを決定します。アプリケーションが主にユーザー固有のリソースのアクセスを提供する場合、このアプローチが有効です。オペレーティング システム レベルの監査をアプリケーションの各層にわたって実行できることは、より優れた長所となっています。その理由は、本来の呼び出し元のセキュリティ コンテキストがオペレーティング システムのレベルでフローし、リソース アクセスに使用されているからです。ただし、このアプローチは、データベース アクセスのための効果的な接続プールが不可能なことから、アプリケーションの拡張性が低いという短所があります。その結果、このアプローチは、限定された規模のイントラネットベース アプリケーションで最もよく利用されています。図 4.5 に、偽装モデルを示します。

図 4.5
エンド ユーザー別承認レベルの粒度を示す偽装モデル
最小の粒度でも最大の拡張性を持つアプローチでは、アプリケーションのプロセス識別情報を使用したリソース アクセスが行われます。この手法は、データベース接続プールに対応しますが、データベース内のアプリケーションの識別情報に付与されたアクセス許可が共通で、元の呼び出し元の識別情報とは無関係です。1 次承認はアプリケーションの論理的な中間層で実行されます。この場合に使用されるロールは、アプリケーション内で同じ権限を共有するユーザーをグループにまとめます。クラスとメソッドへのアクセスは呼び出し元のロール メンバシップに基づいて制限されます。ユーザー別のデータ取得に対応するため、データベース テーブル内に識別情報カラムを含め、クエリ パラメータを使用して取得したデータを制限するのが共通の手法です。たとえば、ストアド プロシージャ パラメータを使用して、(オペレーティング システム レベルではなく) アプリケーション レベルで元の呼び出し元の識別情報をデータベースに渡し、次のようにクエリを記述できます。
SELECT field1, field2, field3 FROM Table1 WHERE {検索条件} AND
UserName = @originalCallerUserName
このモデルは、信頼されたサブシステム、または信頼されたサーバー モデルとも呼ばれます。このモデルを図 4.6 に示します。

図 4.6
データベース接続プールをサポートする信頼されたサブシステム モデル
3 つ目のオプションは、限定された識別情報のセットを使用して、呼び出し元のロール メンバシップに基づいたリソースのアクセスを行う方法です。これは、前の 2 つのモデルの混成になります。呼び出し元はアプリケーションの論理的な中間層のロールにマップされ、クラスとメソッドへのアクセスはロール メンバシップに基づいて制限されます。ダウンストリーム リソースのアクセスは、現在の呼び出し元のロール メンバシップによって決定される限定された識別情報のセットを使用して実行されます。このアプローチの長所は、データベースへのログインごとに権限を割り当てることができ、接続プールが複数存在しても有効なことです。短所は、Windows 認証を使用したダウンストリーム リソースへアクセスするために、異なるセキュリティ コンテキストを確立することです。これに使用される複数のスレッド アクセス トークンを作成することは、権限の必要な処理であり、権限を持つプロセス アカウントが必要です。これは、権限を最小限にする原則に反します。図 4.7 に、ダウンストリーム リソースのアクセスのために複数の信頼されたサービス識別情報を使用したハイブリッド モデルを示します。

図 4.7
ハイブリッド モデル
構成管理
Web アプリケーションの構成管理機能は、慎重に検討します。多くのアプリケーションでは、コンテンツ開発者、オペレータ、管理者がアプリケーションを構成し、Web ページのコンテンツ、ユーザー アカウント、ユーザー プロファイル情報、データベース接続文字列などのアイテムを管理できるようにするインターフェイスが必要です。リモート管理がサポートされている場合、管理インターフェイスのセキュリティはどのようにして保護されるのでしょうか。管理インターフェイスに対するセキュリティ違反によって、攻撃者が頻繁に管理者権限を行使して、サイト全体に直接アクセスする可能性があるため、深刻な影響を及ぼします。
次の方法を使用すると、Web アプリケーションの構成管理のセキュリティを改善できます。
-
管理インターフェイスをセキュリティで保護します。
-
構成ストアをセキュリティで保護します。
-
個別の管理者特権を保守します。
-
最小限の権限を持つプロセス アカウントとサービス アカウントを使用します。
管理インターフェイスをセキュリティで保護する
構成管理機能は、許可されたオペレータ、および管理者だけしかアクセスできないことが重要です。重要な部分は、たとえば、証明書を使用することによって、管理インターフェイス上で強力な認証を実行することです。
可能であれば、リモート管理の使用を制限するか、これを回避して、管理者がローカルにログオンすることを要求します。リモート管理をサポートする必要がある場合、管理インターフェイス上を通過するデータは本質的に機密性が高いことから、たとえば SSL や VPN 技術によって暗号化されたチャネルを使用します。さらに、IPSec ポリシーを使用することで、リモート管理を内部ネットワーク上のコンピュータに制限し、リスクを一段と軽減することを検討します。
構成ストアをセキュリティで保護する
テキストベースの構成ファイル、レジストリ、データベースは、アプリケーション構成データを格納するための共通のオプションです。可能であれば、アプリケーションの Web 空間では構成ファイルの使用を避け、構成ファイルのダウンロードに起因する可能性のあるサーバー構成の脆弱性を防ぎます。使用するアプローチに関係なく、たとえば Windows ACL またはデータベース権限を使用することで、構成ストアへのアクセスをセキュリティで保護します。さらに、データベース接続文字列やアカウント資格情報などのプレーンテキストの機密情報を格納しないようにします。暗号化によってこれらのアイテムをセキュリティで保護し、暗号化されたデータを含むレジストリ キー、ファイル、テーブルへのアクセスを制限します。
個別の管理者特権
アプリケーションの構成管理機能がサポートする機能性が管理者の役割 (ロール) によって異なる場合、ロール ベースの承認によって、各役割を個別に承認する方法を検討します。たとえば、サイトの静的なコンテンツを更新する担当者が、顧客のクレジット制限を変更できるようにする必要はありません。
最小限の権限を持つプロセス アカウントとサービス アカウントを使用する
アプリケーションの構成における重要な側面に、Web サーバー プロセスの実行に使用されるプロセス アカウントと、ダウンストリームのリソースとシステムのアクセスに使用されるサービス アカウントがあります。これらのアカウントは、最小限の権限を持つように設定するようにします。攻撃者がプロセスの管理を掌握した場合、可能性のある損害を抑えるため、プロセスの識別情報によるファイル システム、その他のシステム リソースへのアクセス制限を厳しくする必要があります。
機密性の高いデータ
クレジット カード番号、住所、病歴、といった個人的なユーザー情報を扱うアプリケーションは、特殊な手順によってデータのプライバシーを守り、変更できないようにする必要があります。さらに、パスワードやデータベース接続文字列など、アプリケーションの実装に使用される機密情報はセキュリティで保護する必要があります。機密性の高いデータは、データが永続的なストレージに格納される場合と、ネットワーク上でやり取りされる場合にセキュリティが問題になります。
機密情報
機密情報には、パスワード、データベース接続文字列、クレジット カード番号があります。次の方法を使用すると、Web アプリケーションの機密情報の処理を改善できます。
-
機密情報はなるべく保存しないようにします。
-
機密情報をコードに保存しないようにします。
-
データベース接続、パスワード、またはキーをプレーンテキストで保存しないようにします。
-
ローカル セキュリティ機関 (LSA) に機密情報を格納しないようにします。
-
機密情報の暗号化にはデータ保護 API (DPAPI) を使用します。
機密情報はなるべく保存しない
完全に安全な方法でソフトウェアに機密情報を保存するのは不可能です。管理者はサーバーに対して物理的にアクセスできると同時にデータにアクセスできます。たとえば、ユーザーが機密情報を知っているかどうかを検証するだけでよい場合、機密情報を保存する必要はありません。この場合、機密情報を意味するハッシュ値を格納し、ユーザー指定の値を使用してそのハッシュを計算することで、ユーザーが機密情報を知っているかどうかを検証することができます。
機密情報をコードに保存しない
コードの機密情報をハード コードしないようにします。ソース コードが Web サーバー上で公開されていなくても、コンパイル済みの実行可能ファイルから文字列定数を抽出することは可能です。構成の脆弱性によって、攻撃者が実行可能形式を取り出すことが可能になることがあります。
データベース接続、パスワード、またはキーをプレーンテキストで保存しない
データベース接続文字列、パスワード、またはキーなどの識別情報をプレーンテキストで保存しないようにします。暗号化を使用し、暗号化された文字列を格納します。
LSA に機密情報を格納しない
アプリケーションでは LSA にアクセスするために管理者権限が必要なため、LSA を使用しないようにします。これは、最小限の権限で運用するという中心的なセキュリティ原則に違反するものです。さらに、LSA は限定された数のスロットにだけ機密情報を格納できます。Microsoft® Windows® 2000 以降のオペレーティング システムで使用可能な DPAPI を使用する方が適しています。
機密情報の暗号化に DPAPI を使用する
データベース接続文字列、またはサービス アカウント資格情報などの機密情報を格納するには、DPAPI を使用します。DPAPI を使用する主な長所は、プラットフォーム システムが暗号化と解読キーを管理することであり、アプリケーションの長所ではありません。キーは、DPAPI 関数に渡されたフラグに応じて、Windows ユーザー アカウント、または特定のコンピュータに結合されます。
DPAPI が最も適しているのは、マスタ キーを紛失した場合に手動で再度作成できる情報の暗号化です。これは、被害を受けたサーバーにはオペレーティング システムの再インストールが必要なためです。顧客のクレジット カードの明細など、プレーンテキストの値を知らないために復元できないデータには、TripleDES を使用するなど、従来のキーベースの対称暗号化を使用した別のアプローチが必要です。
Web アプリケーションから DPAPI を使用する場合の詳細については、モジュール 10「セキュリティ保護された ASP.NET ページとコントロールを構築する」を参照してください。
機密性の高いユーザー別データ
ログオン資格情報などの機密性の高いデータ、およびクレジット カード番号、口座番号などのアプリケーション レベルのデータは保護の対象となります。暗号化によるプライバシーとメッセージ認証コード (MAC) による完全性は重要な要素になります。
次の方法によって、Web アプリケーションの機密性の高いユーザー別データについてセキュリティを改善します。
-
オン デマンドで機密性の高いデータを取得します。
-
データを暗号化するか、通信チャネルをセキュリティで保護します。
-
機密性の高いデータを永続的な Cookie に格納しないようにします。
-
HTTP-GET プロトコルを使用して機密性の高いデータを渡さないようにします。
オン デマンドで機密性の高いデータを取得する
推奨されるアプローチは、メモリに保持したり、キャッシュする代わりに、必要なときにオン デマンドで機密性の高いデータを取得することです。たとえば、必要な場合に暗号化された機密情報を取得、解読、使用し、そのプレーンテキストの機密情報を保持するために使用されたメモリ (可変) を消去します。パフォーマンスが問題になる場合は、次のオプションを検討します。
-
暗号化された機密情報をキャッシュします。
-
プレーンテキストの機密情報をキャッシュします。
暗号化された機密情報をキャッシュする
アプリケーションのロード時に機密情報を取得し、暗号化された機密情報をメモリにキャッシュし、アプリケーションで使用するときに解読します。必要がなくなったら、プレーンテキストのコピーを消去します。これにより、要求ごとにデータ ストアにアクセスすることを回避できます。
暗号化された機密情報をキャッシュする
機密情報を何度も解読する負荷を回避し、機密情報のプレーンテキスト コピーをメモリに格納します。この方法は、最低限のセキュリティで保護し、最適なパフォーマンスを実現します。これによって得られるパフォーマンスの向上が、追加されるセキュリティ リスクに見合ったものであると判断する前に、別のアプローチのベンチマークを実行してください。
データを暗号化するか、通信チャネルをセキュリティで保護する
ネットワーク上で機密性の高いデータをクライアントに送信する場合、データを暗号化するか、チャネルをセキュリティで保護します。一般的な方法は、クライアントと Web サーバー間で SSL を使用します。サーバー間では、IPSec を使用する方法がさらに一般的になっています。たとえば、Web サービスの Simple Object Access Protocol (SOAP) メッセージなどの、複数の媒介を経由してフローする機密性の高いデータをセキュリティで保護する場合には、メッセージ レベルの暗号化を使用します。
機密性の高いデータを永続的な Cookie に格納しない
機密性の高いデータを永続的な Cookie に格納しないようにします。プレーンテキスト データを格納した場合、エンド ユーザーはそのデータを参照し、修正することができます。データを暗号化する場合は、キーの管理が問題になる可能性があります。Cookie のデータの暗号化に使用するキーの有効期限が切れて、再使用された場合、新しいキーはブラウザによって渡されたクライアントの永続的な Cookie を解読することはできません。
HTTP-GET プロトコルを使用して機密性の高いデータを渡さないようにする
HTTP-GET プロトコルはクエリ文字列を使用してデータを渡すため、このプロトコルを使用して機密性の高いデータを格納するのは避ける必要があります。機密性の高いデータは、クエリ文字列を使用してセキュリティで保護することはできず、多くの場合、サーバーがクエリ文字列記録します。
セッション管理
Web アプリケーションはステートレスな HTTP プロトコル上に構築されるため、セッション管理はアプリケーション レベルで実行されます。セッション セキュリティは、アプリケーションのセキュリティ全体にとって不可欠です。
次の方法を使用すると、Web アプリケーションのセッション管理のセキュリティを改善できます。
-
SSL を使用してセッション認証 Cookie を保護します。
-
認証 Cookie の内容を暗号化します。
-
セッションの継続時間を制限します。
-
セッション状態を不正なアクセスから保護します。
SSL を使用してセッション認証 Cookie を保護する
HTTP 接続上で認証 Cookie を渡さないでください。認証 Cookie 内に安全な Cookie プロパティを設定します。このプロパティによって、ブラウザによりHTTP 接続上でのみ Cookie をサーバーに送信されます。詳細については、モジュール 10「セキュリティ保護された ASP.NET ページとコントロールを構築する」を参照してください。
認証 Cookie の内容を暗号化する
SSL を使用する場合にも、認証 Cookie の内容を暗号化します。これによって、XXS 攻撃によって Cookie が攻撃者に盗難された場合に、攻撃者がその Cookie を表示し、修正することを防ぐことができます。この場合、攻撃者はその Cookie を使用してアプリケーションにアクセスすることができますが、その Cookie が有効な期間内に限られます。
セッションの継続時間を制限する
セッションの有効期限を短縮して、セッションのハイジャックとリプレイ攻撃のリスクを緩和します。セッションが短くなるほど、攻撃者がセッション Cookie を取得して、アプリケーションにアクセスする時間も短くなります。
セッション状態を不正なアクセスから保護する
セッション状態を格納する方法を検討します。最適なパフォーマンスを得るために、セッションの状態を Web アプリケーションのプロセス アドレス空間に格納することができます。ただし、Web ファームの場合は、同じユーザーからの要求を同じサーバーで処理することは許可されません。このため、このアプローチの拡張性と影響には制約があります。この場合は、専用の状態サーバー上のアウト プロセス状態ストアか、または共有データベース内の永続的な状態ストアが必要です。ASP.NET は 3 つのオプションをすべてサポートしています。
傍受のリスクを小さくするために、Web アプリケーションから状態ストアへのネットワーク リンクは、IPSec または SSL を使用してセキュリティで保護する必要があります。さらに、Web アプリケーションを状態ストアによって認証する方法についても検討します。プレーンテキストの認証資格情報がネットワーク上を通過することを回避できる場合と、セキュリティで保護された Windows アカウント ポリシーが活用できる場合は、Windows 認証を使用します。
暗号化
基本的な形式の暗号化は、以下を提供します。
-
プライバシー (機密性) - このサービスは、機密情報を守ります。
-
否認防止 (信頼性) - ユーザーが特定のメッセージの送信を拒否できないようにします。
-
改ざん防止 (完全性) - データが改ざんされないようにします。
-
認証 - メッセージの送信者の識別情報を確認します。
Web アプリケーションは、永続的なストアのデータをセキュリティで保護する場合、またはネットワーク上でデータを転送する場合に、暗号化を頻繁に使用します。次の方法を使用すると、暗号化を使用する場合の Web アプリケーションのセキュリティを改善できます。
-
独自の暗号化を開発しないでください。
-
暗号化されていないデータは、使用する直前にアルゴリズムに渡します。
-
正しいアルゴリズムと正しいキー サイズを使用します。
-
暗号化キーをセキュリティで保護します。
独自の暗号化を開発しない
暗号化アルゴリズムとルーチンは、周知のとおり、開発が困難です。したがって、試用とテスト済みのプラットフォームが提供する暗号化サービスを使用する必要があります。これには、.NET Framework と基底にあるオペレーティング システムが含まれます。カスタマイズされた実装を開発すると、多くの場合、脆弱な保護機能になります。
暗号化されていないデータは使用する直前にアルゴリズムに渡す
プレーンテキストをアルゴリズムに渡す場合、データを使用する準備ができてから取得し、できるだけ少ない数の変数に格納します。
正しいアルゴリズムと正しいキー サイズを使用する
正しいジョブに適切なアルゴリズムを選択すること、十分なセキュリティ レベルを提供するキー サイズを使用することが重要です。通常、キー サイズが長くなるほど、セキュリティが強化されます。次の一覧は、主なアルゴリズムと使用されるキー サイズの対応を示します。
-
Data Encryption Standard (DES) 64 ビット キー (8 バイト)
-
TripleDES 128 ビット キー、または 192 ビット キー (16 または 24 バイト)
-
Rijndael 128 256 ビット キー (16 32 バイト)
-
Rijndael 384 16,384 ビット キー (48 2,048 バイト)
大規模なデータ暗号化には、TripleDES 対称暗号化アルゴリズムを使用します。大規模なデータを低速で強力に暗号化するには、Rijndael を使用します。短期間だけ格納するデータを暗号化する場合には、DES などの高速で弱いアルゴリズムを使用することを検討できます。デジタル署名の場合は、Rivest, Shamir, and Adleman (RSA)、または Digital Signature Algorithm (DSA) を使用します。ハッシュの場合は、Secure Hash Algorithm (SHA)1.0 を使用します。キー済みのハッシュの場合は、Hash-based Message Authentication Code (HMAC) SHA1.0 を使用します。
暗号化キーをセキュリティで保護する
暗号化キーは、暗号化処理と解読処理に対する入力に使用される秘密の番号です。暗号化されたデータのセキュリティを維持するには、このキーを保護する必要があります。攻撃者によって解読キーが危険にさらされた場合、暗号化されたデータは安全ではなくなります。
次の方法を使用すると、暗号化キーをセキュリティで保護できます。
-
DPAPI を使用してキー管理を回避します。
-
定期的にキーを循環させます。
DPAPI を使用してキー管理を回避する
前のとおり、DPAPI を使用する主な長所の 1 つに、キー管理問題がオペレーティング システムによって処理されることが挙げられます。DPAPI が使用するキーは、DPAPI 関数を呼び出すプロセス アカウントに関連付けられたパスワードから派生したものです。DPAPI を使用することにより、キー管理の負荷をオペレーティング システムに渡します。
定期的にキーを循環させる
通常、静的な機密情報は時間が経過すると検出される可能性が高くなります。注意する点は次のとおりです。どこかに書き留めていないか。機密情報の管理者が、異動になったり、退社したりしていないか。キーを乱用していないか。
パラメータ操作
パラメータ操作攻撃の場合、攻撃者はクライアントと Web アプリケーション間で送受信されるデータを改ざんします。改ざんされたデータは、クエリ文字列、フォーム フィールド、Cookie、HTTP ヘッダーを使用して送信されたデータである可能性があります。次の方法によって、Web アプリケーションのパラメータ操作をセキュリティで保護できます。
-
機密性の高い Cookie 状態を暗号化します。
-
ユーザーがチェックを回避できないようにします。
-
クライアントから送信されたすべての値を検証します。
-
HTTP ヘッダー情報を信頼しない。
機密性の高い Cookie 状態を暗号化する
Cookie には、セッション識別情報などの機密性の高いデータ、またはサーバー側の承認処理の一部として使用されるデータが含まれる場合があります。このタイプのデータを不正な操作から保護するには、暗号化技術を使用して Cookie の内容を暗号化します。
ユーザーがチェックを回避できないようにする
パラメータを操作することによって、ユーザーがチェックを回避できないようにします。URL パラメータは、ブラウザのアドレスを入力するテキスト ボックスを経由してエンド ユーザーが操作することが可能です。たとえば、URL の http://www.<YourSite>/<YourApp>/sessionId=10 に含まれる値 10 を乱数に変更して別の出力を受信するようにできます。この点は、クライアント側の JavaScript ではなく、サーバー側コードで確認します。クライアント側の JavaScript はブラウザで無効にすることができます。
クライアントから送信されたすべての値を検証する
ユーザーが入力し、変更できるフィールドを制限し、クライアントからの値をすべて検証します。フォーム フィールドにあらかじめ定義された値が含まれている場合には、ユーザーはそれらを変更し、ポストすることで、別の結果を受信することができます。可能な限り、既知の適切な値のみを許可します。たとえば、入力フィールドが都道府県の場合、都道府県の郵便番号と一致する入力だけを許可する必要があります。
HTTP ヘッダー情報を信頼しない
HTTP ヘッダーは、HTTP 要求と HTTP 応答の開始時に送信されます。HTTP ヘッダーの情報は攻撃者が容易にヘッダーを操作することができるため、Web アプリケーションは、この情報に基づいてセキュリティ決定を行わないことを確認することが必要です。たとえば、ヘッダー内の "referer" フィールドには、要求を発生させた Web ページの URL が含まれています。referer フィールドの値は容易に偽造されるため、たとえば、要求が Web アプリケーションによって生成されたページから発生したかどうかを確認する場合、このフィールドの値に基づいてセキュリティ決定は行いません。
例外管理
セキュリティで保護された例外処理によって、特定のアプリケーション レベルのサービス拒否攻撃を阻止することが可能であり、また、攻撃者にとって都合のよい重要なシステム レベルの情報がクライアントに返信されないようにすることができます。たとえば、正しい例外処理が行われないと、データベース スキーマの詳細、オペレーティング システムのバージョン、スタック トレース、ファイル名とパス情報、SQL クエリ文字列などの攻撃者が必要とする情報がクライアントに返される可能性があります。
適切な方法は、集中化した例外管理とログ ソリューションを設計し、例外管理システムにフックを組み込んで、システム管理者に役立つインスツルメンテーションと集中化監視をサポートします。
次の方法を使用すると、Web アプリケーションの例外管理をセキュリティで保護できます。
-
クライアントに情報をリークしません。
-
エラー メッセージの詳細をログに記録します。
-
例外をキャッシュします。
クライアントに情報を公開しない
エラーが発生した場合、情報の漏えいにつながる可能性のある情報を公開しないでください。たとえば、デバッグ ビルドの際は、関数名、行番号を含むスタック トレースの詳細を公開しないようにします (運用サーバー上では使用しない)。その代わりに、汎用のエラー メッセージをクライアントに返します。
エラー メッセージの詳細をログに記録する
エラー ログには詳細なエラー メッセージを送信します。サービス、またはアプリケーションのユーザーには、たとえば、イベント ログの詳細メッセージにマップできる汎用のエラー メッセージ、カスタム エラー ログ ID などの最小限の情報を送信します。パスワードやその他の機密性の高いデータをログに記録していないことを確認します。
例外をキャッシュする
構造化された例外処理を使用し、例外条件をキャッシュします。アプリケーションを一貫性のない状態にしておくことは、情報の漏えいにつながる可能性がありますが、上記を実行することでこうしたことを回避します。さらに、アプリケーションをサービス拒否攻撃から保護することができます。アプリケーションの内部で例外を適用する方法を決定し、アプリケーション境界で何が発生するのかを特に考慮する必要があります。
.NET アプリケーションの例外管理フレームワークの設計と実装については、MSDN 記事「.NET における例外管理」(http://www.microsoft.com/japan/msdn/net/bda/exceptdotnet.aspx) を参照してください。
監査とログ記録
アプリケーションの各層にわたる動作は監査とログに記録する必要があります。ログを使用することで、疑わしい動作を検出できます。ログは、本格的な攻撃の初期の兆候を示すことが多く、ユーザーが自分のアクションを否認する脅威に対処するのに役立ちます。ログ ファイルは、個人による不正な行為を証明するために、法的な手続きで要求されることがあります。通常、監査がリソースの正確なアクセス時間に、そのリソースにアクセスした同じルーチンによって生成される場合、監査は最も権限を持つとみなされます。
次の方法を使用すると、Web アプリケーションのセキュリティを改善できます。
-
アプリケーションの各層にわたるアクセスを監査し、ログに記録します。
-
識別情報フローを考慮します。
-
主要なイベントをログに記録します。
-
ログ ファイルをセキュリティで保護します。
-
ログ ファイルを定期的にバックアップし、分析します。
アプリケーションの各層にわたるアクセスを監査し、ログに記録する
否認防止のために、アプリケーションの各層にわたるアクセスの監視とログの記録を行います。アプリケーション レベルのログ機能と、Windows、IIS、SQL Server などのプラットフォームの監査機能を組み合わせて使用します。
識別情報フローを考慮する
アプリケーションによって、複数のアプリケーション層にわたって呼び出し元の識別情報をフローさせる方法を検討します。基本的な選択肢は 2 つあります。Kerberos プロトコルの委任を使用して、呼び出し元の識別情報をオペレーティング システム レベルでフローさせることが可能です。これによって、オペレーティング システム レベルの監査を使用することができます。この方法の短所は、中間層に効果的なデータベース接続プールが存在しない可能性があるため、拡張性に影響を与えることです。または、呼び出し元の識別情報をアプリケーション レベルでフローさせて、信頼された識別情報を使用してバックエンド リソースにアクセスすることが可能です。この方法を使用する場合、中間層を信頼する必要があり、潜在的な否認のリスクがあります。中間層に、バックエンドの監査記録と相互に関連付けられる監査記録を生成する必要があります。監査記録を生成するためには、サーバー クロックが同期されていることを確認します。サーバー クロックの同期は、Microsoft Windows 2000 と Active Directory® によって行われます。
主要なイベントをログに記録する
ログに記録する必要のあるイベントのタイプには、試行したログオンの成功および失敗、データ変更、データの取得、ネットワーク通信、そしてログの有効化、無効化などの管理機能があります。ログには、イベントの時間、マシン名などのイベントの場所、現在のユーザーの識別情報、イベントを起動したプロセスの識別情報、さらにイベントの詳細な説明が含まれます。
ログ ファイルをセキュリティで保護する
Windows の ACL を使用してログ ファイルのセキュリティを保護し、ログ ファイルへのアクセスを制限します。これによって、攻撃者が証拠を隠蔽するためにログ ファイルを改ざんすることがさらに困難になります。ログ ファイルを操作する権限を持つ人数は最小限にします。アクセスは、管理者など、高い信頼を持つアカウントでのアクセスに限定します。
ログ ファイルを定期的にバックアップし、分析する
ログ ファイルを分析しない場合は、動作をログに記録しても意味がありません。ログ ファイルは、定期的に運用サーバーから削除する必要があります。削除する頻度は、アプリケーションの動作レベルに依存します。アプリケーションの設計では、分析のためにログ ファイルを取得し、オフライン サーバーに移す方法を検討する必要があります。この目的のために、Web サーバー上で開かれている追加のプロトコルとポートは、安全にロックする必要があります。
設計ガイドラインのまとめ
表 4.1 に、このモジュールで説明されている設計ガイドラインの要約を、アプリケーションの脆弱性のカテゴリ別に整理して示します。
表 4.1: アプリケーションの設計ガイドライン
|
カテゴリ |
ガイドライン |
|---|---|
|
入力検証 |
入力を信頼せず、集中化した入力検証を検討します。 |
|
認証 |
サイトを匿名、識別済み、認証済みエリアに分割します。強力なパスワードを使用します。パスワード有効期限とアカウントの無効化をサポートします。資格情報は保存しません (Salt による一方向のハッシュを使用)。認証トークンを保護するために通信チャネルを暗号化します。フォーム認証 Cookie は HTTP 接続上のみで渡します。 |
|
承認 |
最小限の特権を持つアカウントを使用します。承認レベルの粒度について検討します。権限の分離を実行します。ユーザー アクセスをシステム レベルのリソースに限定します。 |
|
構成管理 |
最小限の権限を持つプロセス アカウントとサービス アカウントを使用します。資格情報はプレーンテキストで保存しません。管理インターフェイス上では、強力な認証と承認を使用します。LSA は使用しません。リモート管理用の通信チャネルをセキュリティで保護します。機密性の高いデータを Web 空間に格納することは避けます。 |
|
機密性の高いデータ |
機密情報の保存は避けます。ケーブル上では機密性の高いデータを暗号化します。通信チャネルをセキュリティで保護します。機密性の高いデータ ストアには強力なアクセス制御を提供します。機密性の高いデータは永続的な Cookie に格納しません。HTTP-GET プロトコルを使用して機密性の高いデータを渡さないでください。 |
|
セッション管理 |
セッションの継続時間を制限します。チャネルをセキュリティで保護します。認証 Cookie の内容を暗号化します。セッション状態を不正なアクセスから保護します。 |
|
暗号化 |
独自の暗号化を開発しないでください。試用とテスト済みのプラットフォーム機能を使用します。暗号化されていないデータは使用する直前にアルゴリズムに渡します。適切なアルゴリズムとキー サイズを使用します。DPAPI を使用し、キー管理は回避します。定期的にキーを循環させます。キーは制限された場所に格納します。 |
|
パラメータ操作 |
機密性の高い Cookie 状態を暗号化します。クライアントが操作できるフィールド (クエリ文字列、フォーム フィールド、Cookie、または HTTP ヘッダー) は信頼しないでください。クライアントから送信されたすべての値を検証します。 |
|
例外管理 |
構造化された例外処理を使用します。機密性の高いアプリケーションの実装の詳細は公表しません。パスワードなどの個人的なデータはログに記録しません。集中化した例外管理フレームワークを検討します。 |
|
監査とログ記録 |
悪意のある動作を識別します。正しいトラフィックの状況を把握します。すべてのアプリケーション層を経由する動作を監査し、ログに記録します。ログ ファイルへのアクセスをセキュリティで保護します。ログ ファイルをバックアップし、定期的に分析します。 |
要約
製品開発のライフ サイクルにおけるすべての段階でセキュリティが浸透している必要があります。また、セキュリティはアプリケーション設計の中心です。強固な認証および承認戦略を設計することに特に注意が必要です。さらに、アプリケーション レベルの攻撃の大半は、悪意のある形式の入力データと不十分なアプリケーションの入力検証が利用されることを覚えておいてください。このモジュールで説明したガイダンスは、安全なアプリケーションの設計と構築において、さまざまな困難を対処していくうえで役立ちます。
その他のリソース
詳細については、以下のリソースを参照してください。
-
このガイドは、ユーザーによる Web アプリケーションのセキュリティ強化の支援を目的としたシリーズの第 II 部になります。設計、デザイン、認証の構築と構成、承認、および配信された Web アプリケーション層全体でのセキュリティで保護された通信については、Microsoft patterns & practices「セキュリティ保護された ASP.NET アプリケーションの構築」(http://www.microsoft.com/japan/msdn/net/security/secnetlpMSDN.aspx) を参照してください。
-
MSDN の記事「第 2 章 ASP.NET アプリケーションのセキュリティ モデル」(http://www.microsoft.com/japan/msdn/net/security/SecNetch02.aspx) を参照してください。
-
MSDN の記事「第 3 章 認証と認定」(http://www.microsoft.com/japan/msdn/net/security/SecNetch03.aspx) を参照してください。