セキュリティ フレーム: 例外管理 |緩和 策

製品/サービス [アーティクル]
WCF
Web API
  • ASP.NET Web API
Web アプリケーション

WCF - 構成ファイルに serviceDebug ノードを含めないでください

タイトル 詳細
コンポーネント WCF
SDL フェーズ 建築する
適用できるテクノロジ ジェネリック、.NET フレームワーク 3
属性 N/A
References MSDN、Fortify Kingdom
手順 Windows Communication Framework (WCF) サービスは、デバッグ情報を公開するように構成できます。 運用環境ではデバッグ情報を使用しないでください。 <serviceDebug> タグは、WCF サービスに対してデバッグ情報機能を有効にするかどうかを定義します。 属性 includeExceptionDetailInFaults が true に設定されている場合、アプリケーションからの例外情報がクライアントに返されます。 攻撃者は、デバッグ出力から得られる追加情報を利用して、アプリケーションによって使用されるフレームワーク、データベース、またはその他のリソースを対象とする攻撃をマウントできます。

例

次の構成ファイルには、 <serviceDebug> タグが含まれています。

<configuration> 
<system.serviceModel> 
<behaviors> 
<serviceBehaviors> 
<behavior name=""MyServiceBehavior""> 
<serviceDebug includeExceptionDetailInFaults=""True"" httpHelpPageEnabled=""True""/> 
... 

サービスのデバッグ情報を無効にします。 これを行うには、アプリケーションの構成ファイルから <serviceDebug> タグを削除します。

WCF - 構成ファイルに serviceMetadata ノードを含めないでください

タイトル 詳細
コンポーネント WCF
SDL フェーズ 建築する
適用できるテクノロジ ジェネリック
属性 ジェネリック、.NET フレームワーク 3
References MSDN、Fortify Kingdom
手順 サービスに関する情報を公開すると、攻撃者はサービスを悪用する方法に関する貴重な洞察を得ることができます。 <serviceMetadata> タグを使用すると、メタデータ発行機能が有効になります。 サービス メタデータには、パブリックにアクセスできない機密情報が含まれている可能性があります。 少なくとも、信頼できるユーザーのみがメタデータにアクセスし、不要な情報が公開されないようにします。 さらに、メタデータを発行する機能を完全に無効にすることをお勧めします。 安全な WCF 構成には、 <serviceMetadata> タグは含まれません。

ASP.NET Web APIで適切な例外処理が行われることを確認する

タイトル 詳細
コンポーネント Web API
SDL フェーズ 建築する
適用できるテクノロジ MVC 5、MVC 6
属性 N/A
References exception Handling in ASP.NET Web API, Model Validation in ASP.NET Web API
手順 既定では、ASP.NET Web APIでキャッチされないほとんどの例外は、状態コード 500, Internal Server Error を含む HTTP 応答に変換されます。

例

API によって返される状態コードを制御するために、次に示すように HttpResponseException を使用できます。

public Product GetProduct(int id)
{
    Product item = repository.Get(id);
    if (item == null)
    {
        throw new HttpResponseException(HttpStatusCode.NotFound);
    }
    return item;
}

例

例外応答をさらに制御するために、次に示すように HttpResponseMessage クラスを使用できます。

public Product GetProduct(int id)
{
    Product item = repository.Get(id);
    if (item == null)
    {
        var resp = new HttpResponseMessage(HttpStatusCode.NotFound)
        {
            Content = new StringContent(string.Format("No product with ID = {0}", id)),
            ReasonPhrase = "Product ID Not Found"
        }
        throw new HttpResponseException(resp);
    }
    return item;
}

HttpResponseException型ではないハンドルされない例外をキャッチするには、例外フィルターを使用できます。 例外フィルターは、 System.Web.Http.Filters.IExceptionFilter インターフェイスを実装します。 例外フィルターを記述する最も簡単な方法は、 System.Web.Http.Filters.ExceptionFilterAttribute クラスから派生し、OnException メソッドをオーバーライドすることです。

例

NotImplementedException例外を HTTP 状態コード501, Not Implementedに変換するフィルターを次に示します。

namespace ProductStore.Filters
{
    using System;
    using System.Net;
    using System.Net.Http;
    using System.Web.Http.Filters;

    public class NotImplExceptionFilterAttribute : ExceptionFilterAttribute 
    {
        public override void OnException(HttpActionExecutedContext context)
        {
            if (context.Exception is NotImplementedException)
            {
                context.Response = new HttpResponseMessage(HttpStatusCode.NotImplemented);
            }
        }
    }
}

Web API 例外フィルターを登録するには、いくつかの方法があります。

  • アクションごと
  • コントローラー別
  • 世界的に

例

特定のアクションにフィルターを適用するには、アクションに属性としてフィルターを追加します。

public class ProductsController : ApiController
{
    [NotImplExceptionFilter]
    public Contact GetContact(int id)
    {
        throw new NotImplementedException("This method is not implemented");
    }
}

例

controllerのすべてのアクションにフィルターを適用するには、controller クラスに属性としてフィルターを追加します。

[NotImplExceptionFilter]
public class ProductsController : ApiController
{
    // ...
}

例

すべての Web API コントローラーにフィルターをグローバルに適用するには、フィルターのインスタンスを GlobalConfiguration.Configuration.Filters コレクションに追加します。 このコレクション内の例外フィルターは、任意の Web API コントローラー アクションに適用されます。

GlobalConfiguration.Configuration.Filters.Add(
    new ProductStore.NotImplExceptionFilterAttribute());

例

モデルの検証では、次に示すように、モデルの状態を CreateErrorResponse メソッドに渡すことができます。

public HttpResponseMessage PostProduct(Product item)
{
    if (!ModelState.IsValid)
    {
        return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
    }
    // Implementation not shown...
}

ASP.NET Web APIでの例外的な処理とモデル検証の詳細については、参照セクションのリンクを確認してください

エラー メッセージでセキュリティの詳細を公開しない

タイトル 詳細
コンポーネント Web アプリケーション
SDL フェーズ 建築する
適用できるテクノロジ ジェネリック
属性 N/A
References N/A
手順

一般的なエラー メッセージは、機密性の高いアプリケーション データを含めずにユーザーに直接提供されます。 機密データの例を次に示します。

  • サーバー名
  • 接続文字列
  • ユーザー名
  • パスワード
  • SQL プロシージャ
  • 動的 SQL エラーの詳細
  • スタック トレースとコード行
  • メモリに格納されている変数
  • ドライブとフォルダーの場所
  • アプリケーションのインストール ポイント
  • ホストの構成設定
  • その他の内部アプリケーションの詳細

アプリケーション内のすべてのエラーをトラップし、一般的なエラー メッセージを提供し、IIS 内でカスタム エラーを有効にすると、情報漏えいを防ぐことができます。 SQL Serverデータベースと.NET例外処理を含むエラー処理アーキテクチャは、アプリケーションをプロファイリングする悪意のあるユーザーにとって非常に詳細で役立ちます。 .NET Exception クラスから派生したクラスの内容を直接表示しないでください。また、予期しない例外が誤ってユーザーに直接発生しないように、適切な例外処理があることを確認してください。

  • 例外/エラー メッセージで直接見つかった特定の詳細を抽象化する汎用エラー メッセージをユーザーに直接提供する
  • .NET例外クラスの内容をユーザーに直接表示しない
  • すべてのエラー メッセージをトラップし、必要に応じて、アプリケーション クライアントに送信された汎用エラー メッセージを使用してユーザーに通知します
  • Exception クラスの内容、特に .ToString()からの戻り値、または Message プロパティまたは StackTrace プロパティの値をユーザーに直接公開しないでください。 この情報を安全にログに記録し、より無害なメッセージをユーザーに表示する

既定のエラー処理ページを実装する

タイトル 詳細
コンポーネント Web アプリケーション
SDL フェーズ 建築する
適用できるテクノロジ ジェネリック
属性 N/A
References [エラー ページ設定 ASP.NET 編集] ダイアログ ボックス
手順

ASP.NET アプリケーションが失敗し、HTTP/1.x 500 内部サーバー エラーが発生した場合、または機能の構成 (要求フィルター処理など) によってページが表示されない場合、エラー メッセージが生成されます。 管理者は、アプリケーションでクライアントにわかりやすいメッセージを表示するか、詳細なエラー メッセージをクライアントに表示するか、詳細なエラー メッセージを localhost のみに表示するかを選択できます。 web.config の <customErrors> タグには、次の 3 つのモードがあります。

  • オン: カスタムエラーが有効になっていることを指定します。 defaultRedirect 属性が指定されていない場合、ユーザーには一般的なエラーが表示されます。 カスタム エラーは、リモート クライアントとローカル ホストに表示されます。
  • オフ: カスタム エラーを無効にすることを指定します。 詳細な ASP.NET エラーは、リモート クライアントとローカル ホストに表示されます
  • RemoteOnly: カスタム エラーがリモート クライアントにのみ表示され、ASP.NET エラーがローカル ホストに表示されることを指定します。 これがデフォルト値です

アプリケーション/サイトの web.config ファイルを開き、タグに <customErrors mode="RemoteOnly" /> または <customErrors mode="On" /> 定義されていることを確認します。

IIS で展開方法を Retail に設定する

タイトル 詳細
コンポーネント Web アプリケーション
SDL フェーズ デプロイメント
適用できるテクノロジ ジェネリック
属性 N/A
References deployment 要素 (ASP.NET Settings Schema)
手順

<deployment retail> スイッチは、運用 IIS サーバーで使用することを目的としています。 このスイッチは、アプリケーションがページでトレース出力を生成する機能を無効にし、エンド ユーザーに詳細なエラー メッセージを表示する機能を無効にし、デバッグ スイッチを無効にすることで、可能な限り最高のパフォーマンスと最小限のセキュリティ情報漏えいでアプリケーションを実行するために使用されます。

多くの場合、失敗した要求のトレースやデバッグなど、開発者に重点を置いたスイッチとオプションは、アクティブな開発中に有効になります。 運用サーバー上の展開方法を商用に設定することをお勧めします。 machine.config ファイルを開き、 <deployment retail="true" /> が true に設定されていることを確認します。

例外は安全に処理される必要があります

タイトル 詳細
コンポーネント Web アプリケーション
SDL フェーズ 建築する
適用できるテクノロジ ジェネリック
属性 N/A
References 安全な方法で失敗する
手順 アプリケーションは安全に失敗するべきです。 特定の決定に基づいてブール値を返すメソッドには、例外ブロックを慎重に作成する必要があります。 例外ブロックが不注意に書き込まれると、セキュリティの問題が忍び込むため、多くの論理エラーが発生します。

例

        public static bool ValidateDomain(string pathToValidate, Uri currentUrl)
        {
            try
            {
                if (!string.IsNullOrWhiteSpace(pathToValidate))
                {
                    var domain = RetrieveDomain(currentUrl);
                    var replyPath = new Uri(pathToValidate);
                    var replyDomain = RetrieveDomain(replyPath);

                    if (string.Compare(domain, replyDomain, StringComparison.OrdinalIgnoreCase) != 0)
                    {
                        //// Adding additional check to enable CMS urls if they are not hosted on same domain.
                        if (!string.IsNullOrWhiteSpace(Utilities.CmsBase))
                        {
                            var cmsDomain = RetrieveDomain(new Uri(Utilities.Base.Trim()));
                            if (string.Compare(cmDomain, replyDomain, StringComparison.OrdinalIgnoreCase) != 0)
                            {
                                return false;
                            }
                            else
                            {
                                return true;
                            }
                        }

                        return false;
                    }
                }

                return true;
            }
            catch (UriFormatException ex)
            {
                LogHelper.LogException("Utilities:ValidateDomain", ex);
                return true;
            }
        }

何らかの例外が発生した場合、上記のメソッドは常に True を返します。 エンドユーザーが形式が正しくない URL を提供し、ブラウザーが対応するが Uri() コンストラクターは対応しない場合、これにより例外が発生し、被害者は有効だが形式が正しくない URL に誘導されます。