セキュリティ フレーム:例外管理 | 対応策
製品/サービス | [アーティクル] |
---|---|
WCF | |
Web API | |
Web アプリケーション |
WCF- serviceDebug ノードを構成ファイルに含めない
タイトル | 詳細 |
---|---|
コンポーネント | WCF |
SDL フェーズ | Build |
適用できるテクノロジ | ジェネリック、NET Framework 3 |
属性 | 該当なし |
参照 | 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 フェーズ | Build |
適用できるテクノロジ | ジェネリック |
属性 | ジェネリック、NET Framework 3 |
参照 | MSDN、Fortify Kingdom |
手順 | サービスに関する情報を公開すると、サービスの悪用について攻撃者に多くの洞察を与えてしまう可能性があります。
<serviceMetadata> タグにより、メタデータの公開機能が有効化されます。 サービス メタデータには、パブリックにアクセスできないようにする必要がある機密情報が含まれている可能性があります。 少なくとも、信頼されたユーザーにのみメタデータへのアクセスを許可し、不要な情報は公開されないことを確認してください。 メタデータを公開する機能をすべて無効にすると、より安全です。 安全な WCF 構成には <serviceMetadata> タグが含まれません。 |
ASP.NET Web API で適切な例外処理が実行されたことを確認する
タイトル | 詳細 |
---|---|
コンポーネント | Web API |
SDL フェーズ | Build |
適用できるテクノロジ | MVC 5、MVC 6 |
属性 | 該当なし |
参照 | ASP.NET Web API での例外処理、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 フェーズ | Build |
適用できるテクノロジ | ジェネリック |
属性 | 該当なし |
参照 | 該当なし |
手順 | 一般的なエラー メッセージは、機密性の高いアプリケーション データを含まずに、ユーザーに直接提供されます。 機密データの例は次のとおりです。
IIS 内でのカスタム エラーを有効にするだけでなく、アプリケーション内のすべてのエラーをトラップし、一般的なエラー メッセージを提供すると、情報漏えいを防ぐことができます。 SQL Server データベースと .NET の例外処理は、その他のエラー処理アーキテクチャの中でも特に詳細であり、アプリケーションをプロファイリングする悪意のあるユーザーにとっては非常に便利なものです。 .NET 例外クラスから派生するクラスの内容は、直接表示しないでください。また、予期しない例外がユーザーに誤って直接表示されることがないように、適切な例外処理が行われることを確認してください。
|
既定のエラー処理ページを実装する
タイトル | 詳細 |
---|---|
コンポーネント | Web アプリケーション |
SDL フェーズ | Build |
適用できるテクノロジ | ジェネリック |
属性 | 該当なし |
参照 | ASP.NET エラー ページ設定の編集ダイアログ ボックス |
手順 | ASP.NET アプリケーションでエラーが生じ、HTTP/1.x 500 内部サーバー エラーが発生した場合、または機能構成 (要求フィルターなど) が原因でページが表示されない場合、エラー メッセージが生成されます。 管理者は、アプリケーションでクライアントにわかりやすいメッセージを表示するか、クライアントに詳細なエラー メッセージを表示するか、localhost のみに詳細なエラー メッセージを表示するかを選択できます。 web.config 内の
アプリケーション/サイトの |
IIS の deployment メソッドを retail に設定する
タイトル | 詳細 |
---|---|
コンポーネント | Web アプリケーション |
SDL フェーズ | デプロイ |
適用できるテクノロジ | ジェネリック |
属性 | 該当なし |
参照 | deployment 要素 (ASP.NET 設定スキーマ) |
手順 |
多くの場合、失敗した要求トレースやデバッグなどの開発者向けスイッチおよびオプションが、開発中に有効化されています。 すべての実稼働サーバーの deployment メソッドを retail に設定することをお勧めします。 machine.config ファイルを開き、 |
例外は安全に失敗する必要がある
タイトル | 詳細 |
---|---|
コンポーネント | Web アプリケーション |
SDL フェーズ | Build |
適用できるテクノロジ | ジェネリック |
属性 | 該当なし |
参照 | 安全な失敗 |
手順 | アプリケーションは安全に失敗する必要があります。 特定の意思決定に基づいてブール値を返すすべてのメソッドでは、例外ブロックを慎重に作成する必要があります。 十分に検討せずに例外ブロックを記述すると、セキュリティの問題が潜在する多くの論理エラーが発生します。 |
例
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 を返します。 エンド ユーザーが、ブラウザーでは考慮されているが Uri()
コンストラクターでは考慮されていない正しくない URL を入力した場合、例外が返され、攻撃対象は、有効ではあるものの正しくない URL に誘導されます。