印刷用ページ      送信     
クリックして評価とフィードバックをお寄せください
MSDN
MSDN ライブラリ
Win32 および COM 開発
セキュリティ
セキュリティ (全般)
技術文書
 セキュリティ保護されたリモート コンポーネントを構築する
セキュリティ ガイダンス
セキュリティ保護されたリモート コンポーネントを構築する

 

公開日: 2004年9月7日 | 最終更新日: 2004年9月7日
トピック
モジュールの内容 モジュールの内容
目的 目的
適用対象 適用対象
モジュールの使用方法 モジュールの使用方法
概要 概要
脅威とその対策 脅威とその対策
設計に関する考慮事項 設計に関する考慮事項
入力検証 入力検証
認証 認証
承認 承認
機密性の高いデータ 機密性の高いデータ
サービス拒否 サービス拒否
例外管理 例外管理
監査とログ記録 監査とログ記録
コード アクセス セキュリティ (CAS) に関する考慮事項 コード アクセス セキュリティ (CAS) に関する考慮事項
要約 要約
その他のリソース その他のリソース

モジュールの内容

Microsoft® .NET Framework Remoting は、さまざまなアプリケーション ドメイン (AppDomain)、さまざまなプロセス、および複数のコンピュータに存在するオブジェクトが、互いにシームレスに通信するための、高機能で拡張性の高いフレームワークを提供します。.NET Remoting は、これらの相互通信を透過に行うための、強力でシンプルなプログラミング モデルとランタイム サポートを提供します。

.NET Remoting インフラストラクチャには既定の認証または承認メカニズムはありませんが、リモート コンピュータを ASP.NET でホストし、通信に HttpChannel を使用している場合は、ASP.NET とインターネット インフォメーション サービス (IIS) の認証および承認サービスを使用することができます。

このモジュールでは、セキュリティ保護されたリモート コンポーネントを構築するための推奨事項と方法を説明します。ASP.NET と HttpChannel を使用するコンポーネント、およびカスタムの実行可能ホストと TCPChannel を使用するコンポーネントについて説明します。

目的

このモジュールの目的は次のとおりです。

セキュリティ保護されたコンポーネントを設定および展開する。

リモート コンポーネント間で受け渡される機密性の高いデータを保護する。

適切なホスト プロセスを選択する。

HttpChannel の使い方と TcpChannel の使い方を比較する。

シリアル化攻撃と MarchalByRefObject 攻撃のリスクを低減する。

呼び出し側を認証および承認する。

リモート コンポーネントに対するサービス拒否 (DoS) 攻撃を防ぐ。

.NET Remoting コンポーネントの完全信頼要件に応えるために部分的に信頼された環境で実行すべき内容を理解する。

権限のないアクセス、ネットワーク盗聴、パラメータ改ざんなど一般的な .NET Remoting の脅威を解決するために適用すべき対策を理解する。

適用対象

このモジュールは、次の製品およびテクノロジに適用されます。

Microsoft Windows® 2000 Server および Microsoft Windows Server™ 2003

Microsoft .NET Framework 1.1 および ASP.NET 1.1

モジュールの使用方法

このモジュールから最大限の成果を得るには、以下を参照してください。

モジュール 17 「アプリケーション サーバーをセキュリティ保護する」 を参照してください。モジュール 17 では、中間層のリモート ソリューションのセキュリティ保護について、管理者の視点から説明しています。

このガイドの「チェックリスト」にある「チェックリスト: Remoting をセキュリティ保護する」を参照してください。このチェックリストには、セキュリティ保護された .NET Framework Remoting ソリューションの構築と設定に必要なセキュリティ方法の概要が示されています。

概要

Microsoft .NET Framework Remoting インフラストラクチャには、既定の認証または承認メカニズムがありませんが、ASP.NET でリモート コンポーネントをホストし、通信に HttpChannel を使用している場合は、ASP.NET と IIS の認証および承認サービスを使用できます。

パフォーマンスに問題がある場合は、カスタム ホストと TcpChannel を併用することができます。この方法が実行できるのは、可能な呼び出し側の範囲が IPSec ポリシーの使用など帯域外の技術により慎重に制御され、指定された Web サーバーからの通信だけが許可される、信頼されたサブシステム シナリオだけです。TcpChannel を使用する場合は、独自の認証および承認メカニズムを構築する必要があります。これは、試行と試験済みのプラットフォーム レベルのセキュリティ サービスを使用する原則に反し、開発に多くの作業を必要とします。

このモジュールでは、セキュリティ保護されたリモート コンポーネントを構築するための推奨事項と方法を説明します。ASP.NET と HttpChannel を使用するコンポーネント、およびカスタムの実行可能ホストと TCPChannel を使用するコンポーネントについて説明します。このモジュールで前提とする一般的な開発パターンを図 13.1 に示します。このパターンでは、リモート オブジェクトが中間層アプリケーション サーバー上にあり、ASP.NET Web アプリケーション クライアントからの要求と、エンタープライズ内に展開された Windows アプリケーションからの要求も処理します。

一般的な Remoting の展開

図 13.1
一般的な Remoting の展開

この一般的なシナリオでは、リモート コンポーネントがフロントエンドの Web アプリケーションからの要求を処理します。この場合、Web サーバー上の ASP.NET が呼び出し側の認証と承認を処理します。また、中間層のリモート コンポーネントは、エンタープライズ Windows アプリケーションから頻繁にアクセスされます。

脅威とその対策

Remoting テクノロジを使用するセキュリティ保護されたソリューションを構築するには、関連の脅威について理解する必要があります。Remoting を使用するコンポーネントに対する主な脅威には、次のものがあります。

権限のないアクセス

ネットワーク盗聴

パラメータ改ざん

シリアル化

図 13.2 にこれらの脅威を示します。

Remoting の主な脅威

図 13.2
Remoting の主な脅威

権限のないアクセス

機密性の高い情報や制限された情報を提供するリモート コンポーネントは、権限のないアクセスを防ぐために呼び出し側を認証および承認する必要があります。認証や承認が不十分な場合は、機密性の高い情報や操作への権限のないアクセスに悪用される可能性があります。

脆弱性

リモート ソリューションが権限のないアクセスを受ける原因となる脆弱性には、次のものがあります。

カスタムの Windows サービス ホストを使用しているため、アプリケーション レベルの認証が行われていない。

リモート コンポーネントをホストする中間層アプリケーションと通信できるコンピュータを制限するための IPSec ポリシーを使用していない。

ロール ベースの承認が行われていない。

Remoting エンドポイントへのアクセスを制限するファイル承認が行われていない。

クライアントから渡される IPrincipal オブジェクトを信頼する。

対策

権限のないアクセスを防ぐために実装できる対策は次のとおりです。

フロントエンドの Web アプリケーションでクライアントを認証および承認すること、および中間層アプリケーション サーバーとの通信を IPSec ポリシーを使用して制限すること。これらの対策によって、Web サーバーだけが中間層のアプリケーション サーバーに直接アクセスできるようになります。

ASP.NET を使用してリモート コンポーネントを管理し、Windows 認証を使用してリモート コンポーネントへのアクセスを制限する。

ASP.NET の FileAuthorizationModule を使用する。この対策を実行するには、特定の設定と、Remoting エンドポイントを照合するための物理ファイル (.rem または .soap) を作成する必要があります。

ロール ベースの承認を使用してリモート コンポーネント、リモート コンポーネント クラス、およびメソッドへのアクセスを制限する。この対策を実行するには、URL 承認を使って Remoting エンドポイント (.rem または .soap) へのアクセスを制御するか、クラスまたはメソッド レベルで、主要なアクセス許可要求を使用します。

クライアントが信頼されていない場合は、クライアントから渡される IPrincipal オブジェクトを信頼しない。これは通常、IPSec を使用してクライアント コンピュータの範囲を制限する場合に限り適用できる対策です。

ネットワーク盗聴

攻撃者は、ネットワーク盗聴により、リモート コンピュータ間でネットワークを通じてやりとりされる要求メッセージと応答メッセージを参照することが可能です。たとえば、攻撃者はネットワーク監視ソフトウェアを使用して機密性の高いデータを取得する可能性があります。このデータには、機密性の高いアプリケーション レベルのデータや機密情報が含まれる場合があります。

脆弱性

ネットワーク盗聴によるセキュリティ侵害の原因となる脆弱性には、次のものがあります。

暗号化されていない通信チャネルで使用される基本認証

トランスポート レベルの暗号化の非使用

アプリケーション レベルの暗号化の非使用

対策

ネットワーク盗聴攻撃を防ぐために実装できる対策には、次のものがあります。

SSL や IPSec などのトランスポート レベルの暗号化を使用します。SSL を使用するには、ASP.NET ホストと HttpChannel を使用する必要があります。IPSec は、カスタム ホストおよび TcpChannel と併用できます。

アプリケーション レベルで要求を暗号化して、プライバシを提供します。たとえば、カスタム暗号化シンクを作成して、メッセージ ペイロード全体のうちの一部を暗号化できます。

パラメータ改ざん

パラメータ改ざんとは、クライアントとリモート コンポーネント間でやりとりされるデータが不正に改ざんされることです。たとえば、攻撃者は、リモート コンポーネント宛ての要求メッセージを送信中に傍受して改ざんする可能性があります。

脆弱性

パラメータ改ざんにつながる脆弱性には、以下のものがあります。

不正を防止するためのデジタル署名が行われていないメッセージ

プライバシーを保護し、不正を防止するための暗号化が行われていないメッセージ

対策

パラメータ改ざんの実行を防ぐために実装できる対策には、次のものがあります。

メッセージにデジタル署名します。デジタル署名は、メッセージが送信中に不正に改ざんされなかったことを検証するために受信側で使用されます。

プライバシを保護し、不正を防止するためにメッセージ ペイロードを暗号化します。

シリアル化

シリアル化とは、オブジェクトの内部の状態を、バイトのフラットなストリームに変換するプロセスです。.NET Remoting インフラストラクチャでは、.NET Framework のシリアル化サービスを使用して、クライアントとサーバー間でオブジェクトをやりとりします。悪質なコードによって、サーバーにシリアル化したデータ ストリームが投入され、サーバーで予期しない操作が強制的に実行されてしまう可能性があります。たとえば、悪質なクライアント側コードがオブジェクトを初期化して、サーバーで逆シリアル化を行うときに、サーバーのリソースが消耗されたり、悪質なコードが実行されたりする可能性があります。

脆弱性

シリアル化攻撃が行われる原因となる主な脆弱性は、サーバーがシリアル化されたデータ ストリームを信頼し、ストリームから受信したデータの検証を行わないことです。

対策

シリアル化攻撃を防ぐための対策は、サーバーで逆シリアル化を行うときに各データ項目を検証することです。各フィールドの型、長さ、形式、および範囲を検証します。

設計に関する考慮事項

リモート コンポーネントの開発を始める前に、設計に関して考慮しなければならない事項が多数あります。セキュリティ関連の主要な考慮事項は、次のとおりです。

リモート オブジェクトをインターネットに公開しません。

HttpChannel を使用して ASP.NET のセキュリティ機能を利用します。

信頼されたサーバー シナリオでのみ TcpChannel を使用します。

リモート オブジェクトをインターネットに公開しない

リモート オブジェクトは、インターネットから直接アクセスできない、フロントエンドの Web アプリケーションおよび Web サービスからだけアクセスできる中間層アプリケーション サーバーでのみホストする必要があります。リモート オブジェクトが提供する機能をインターネット クライアントに公開する必要がある場合は、Web サービスを使用して中間層オブジェクトをラップし、Web サービスをインターネットに公開します。

HttpChannel を使用して ASP.NET のセキュリティ機能を利用する

セキュリティが最も重要な問題である場合は、ASP.NET を使用してリモート オブジェクトをホストします。これによって、ASP.NET と IIS が提供する認証、承認、およびセキュリティ保護された通信の機能を利用することができます。たとえば、Windows 認証と SSL を使用すると、ネットワーク上で送信される要求と応答のプライバシと完全性を確保できます。

信頼されたサーバー シナリオでのみ TcpChannel を使用する

パフォーマンス上の理由から TcpChannel をカスタムのホスト プロセスで使用する場合は、組み込みの認証サービスが存在しないことに注意してください。

このため、TcpChannel は信頼されているサーバー シナリオでのみ使用する必要があります。このようなシナリオでは、アップストリームの Web アプリケーションまたは Web サービスで元の呼び出し側を認証および承認してから、中間層リモート コンポーネントを呼び出します。このシナリオを安全に行うためには、IPSec を使用してマシンレベルの認証とセキュリティ保護された通信を行います。IPSec ポリシーでは、選択された Web サーバーから中間層リモート コンポーネント ホストへのトラフィックだけを許可する必要があります。この信頼されたサーバー シナリオを図 13.3 に示します。

信頼されたサーバー シナリオでの Remoting

図13.3
信頼されたサーバー シナリオでの Remoting

IPSec の詳細については、このガイドの「HOWTO」にある「IPSec をポートのフィルタリングと認証に使用する方法」を参照してください。

TcpChannel に関する考慮事項

カスタムの実行可能ホストと TcpChannel を使用しているときに、クライアントの認証と承認の実行をアップストリームの Web アプリケーションに依存できない場合は、独自の認証および承認ソリューションを開発する必要があります。

カスタム ソリューションの一部として、プリンシパル オブジェクトをメソッド パラメータまたは呼び出しのコンテキストのどちらで渡すかを決定します。悪質なクライアント側のコードによって高度なロールを持つ IPrincipal オブジェクトが作成され、サーバーに送信されることを防ぐために、信頼された環境でのみこの作業を行ってください。サーバー実装では、IPrincipal オブジェクトを信頼できるようになってから、それらをロール ベースの認証に使用する必要があります。

また、Security Support Provider Interface (SSPI) の基底になるサービスを使用する方法もあります。このアプローチの詳細については、MSDN 記事「.NET Remoting Security Solution, Part 1: Microsoft.Samples.Security.SSPI Assembly」(英語) (http://msdn.microsoft.com/library/en-us/dndotnet/html/remsspi.asp) を参照してください。

TcpChannel を使用するときにセキュリティ保護された通信を行うためには、IPSec またはカスタム暗号化チャネル シンクを使用して、要求データを暗号化します。

入力検証

Remoting ソリューションを使用する信頼されたサーバー シナリオでは、通常フロントエンドの Web アプリケーションが入力検証を実行します。データは完全に検証されてからリモート コンポーネントに渡されます。リモート コンポーネントに渡されるデータが現在の信頼境界内からだけ届くことを保証できる場合は、アップストリーム コードで入力検証を実行できます。

ただし、エンタープライズ内で実行されている任意のクライアント アプリケーションから Remoting ソリューションにアクセスできる場合には、リモート コンポーネントが入力を検証し、シリアル攻撃や MarshalByRefObject 攻撃を受けないように注意する必要があります。

シリアル化攻撃

オブジェクト パラメータをリモート コンポーネントに渡すには、呼び出しのコンテキストを使用するか、リモート コンポーネントで公開されるメソッドに通常の入力パラメータを通じてそれらのオブジェクト パラメータを渡します。悪質なクライアントは、リモート コンポーネントを攻撃したり、意図しない操作をリモート コンポーネントに実行させるという明確な目的で、オブジェクトをシリアル化してリモート コンポーネントに渡す可能性があります。クライアントを信頼できない場合は、オブジェクト パラメータがサーバーに作成されるため、逆シリアル化されたオブジェクトの各フィールド項目を注意深く検証する必要があります。

MarshalByRefObject 攻撃

System.MarshalByRefObject から派生したオブジェクトでは、クライアントにコール バックするために URL が必要です。コールバック URL が偽造されて、サーバーが別のクライアント コンピュータ (ファイアウォールの後ろにあるコンピュータなど) に接続されてしまう可能性があります。

.NET Framework バージョン 1.1 でシリアル化と MarshalByRefObject 攻撃のリスクを低減するためには、<formatter> 要素の typeFilterLevel 属性を Low に設定します。これによって、.NET Framework Remoting インフラストラクチャはメソッドの呼び出しを実行する必要がある場合にだけそれらのオブジェクトをシリアル化し、ユーザーが作成して呼び出しコンテキストに挿入するかパラメータとして渡す、シリアル化をサポートするカスタム オブジェクトは拒否します。この設定は、次のように Web.config ファイルで設定するか、プログラムにより設定できます。

<formatter ref="binary" typeFilterLevel="Low" />

または

BinaryServerFormatterSinkProvider provider = new 
BinaryServerFormatterSinkProvider();
provider.TypeFilterLevel = TypeFilterLevel.Low;

認証

リモート コンポーネントが機密性の高いデータや操作を公開する場合は、その呼び出し側を認証して承認をサポートする必要があります。.NET Framework Remoting インフラストラクチャは、認証モデルを定義していないため、ホストが認証を処理する必要があります。たとえば、ASP.NET を使用して ASP.NET と IIS の認証機能を利用することができます。

カスタムの Windows サービス ホストを使用している場合は、カスタムの認証ソリューションを作成します。

ASP.NET によるホスト

ASP.NET ホストを HttpChannel と共に使用する場合には、次のガイドラインが適用されます。

IIS で匿名認証を無効にします。

ASP.NET を Windows 認証用に設定します。

クライアントの資格情報を設定します。

認証された接続を共有してパフォーマンスを向上します。

呼び出しごとにクライアントを強制的に認証します。

認証されている接続の使用を制御します。

IIS で匿名認証を無効にする

呼び出し側を IIS で認証するためには、アプリケーションの仮想ディレクトリで匿名認証をサポートしないようにします。Windows Server 2003 では、.NET Passport 認証も無効にする必要があります。

IIS の匿名認証を無効にすると、サポートされているどの IIS 認証メカニズム (基本認証、ダイジェスト認証、統合 Windows 認証) でも、HttpChannel で呼び出し側を認証できます資格情報がネットワーク上で渡されないようにするため、および Windows 2000 のセキュリティ アカウントとパスワード ポリシーを利用するためには、統合 Windows 認証を使用します。

ASP.NET を Windows 認証用に設定する

アプリケーションを、Windows 認証用に設定するには、Web.config で次のように設定します。

<authentication mode="Windows" />

Passport 認証やフォーム認証は、ログイン ページへのリダイレクトが必要であるため、使用できません。

注: Windows 認証を使用する場合は、ファイル承認を有効にすることをお勧めします。詳細については、このモジュールで後述する「承認」を参照してください。

クライアントの資格情報を設定する

Windows 認証用に設定されたリモート コンポーネントと正しく通信するために、クライアントは、認証に使用する資格情報を使って Remoting プロキシを設定する必要があります。この設定を実行しない場合、アクセス拒否エラーが発生します。

既定の資格情報を使用してクライアントの現在のスレッドまたはプロセス トークンを使用するように設定するか、明示的な資格情報を設定することができます。

既定の資格情報を使用する

クライアントのプロセス トークン (クライアントのスレッドが現在偽造している場合はスレッド トークン) を使用するには、クライアント プロキシの useDefaultCredentials プロパティを true に設定します。この結果、クライアントがサーバーから認証チャレンジを受け取るときに CredentialsCache.DefaultCredentials が使用されます。プロキシを設定するには、構成ファイルを使用するか、コードでプログラムにより設定します。プロキシを外部で設定するには、クライアントの構成ファイルで次の要素を使用します。

<channel ref="http client" useDefaultCredentials="true" />

既定の資格情報をプログラムにより設定するには、次のコードを使用します。

IDictionary channelProperties;
channelProperties = ChannelServices.GetChannelSinkProperties(proxy);
channelProperties ["credentials"] = CredentialCache.DefaultCredentials;

偽造用に設定されている ASP.NET クライアント アプリケーションで既定の資格情報を使用する場合は、スレッド レベルの偽造トークンが使用されます。これを行うには、Kerberos 委任が必要です。

別の資格情報を使用する

リモート オブジェクトを呼び出すときに認証用の特定の資格情報セットを使用するには、構成ファイル内で次のように設定して既定の資格情報の使用を無効にします。

<channel ref="http" useDefaultCredentials="false" />

注: プログラムによる設定は、構成ファイルの設定よりも常に優先されます。

また、次のコードを使用して、特定の資格情報を使用するようにプロキシを設定します。

IDictionary channelProperties =  
ChannelServices.GetChannelSinkProperties(proxy);
NetworkCredential credentials;
credentials = new NetworkCredential("username", "password", "domain");
ObjRef objectReference = RemotingServices.Marshal(proxy);
Uri objectUri = new Uri(objectReference.URI);
CredentialCache credCache = new CredentialCache();
// "authenticationType" を "Negotiate"、"Basic"、"Digest" 
// "Kerberos" または "NTLM" のいずれかで置き換えます。
credCache.Add(objectUri, "authenticationType", credentials);
channelProperties["credentials"] = credCache;
channelProperties["preauthenticate"] = true;

認証された接続を共有してパフォーマンスを向上させる

useDefaultCredentials="true" と設定している場合は、クライアント側の useAuthenticatedConnectionSharing も true に設定する必要があります。これによって、サーバーは受信した各呼び出しを認証せずに、認証された接続を再利用できるようになります。

<channel ref="http client" useAuthenticatedConnectionSharing="true" >

この機能は、.NET Framework のバージョン 1.1 で HttpChannel を使用している場合にのみ利用できます。

呼び出しごとにクライアントで強制的に認証を行う

unsafeAuthenticatedConnectionSharing を false に設定して、クライアントが独自の資格情報と接続グループ名をサーバーに提供できないようにします。

これを true に設定すると、認証されていないクライアントが、前に認証されたクライアントの資格情報を使用してサーバーに認証を行う可能性があります。useAuthenticatedConnectionSharing プロパティが true に設定されている場合、この設定は無視されます。この設定では、サーバーとの各接続が閉じて、呼び出しごとにクライアントが認証を行う必要があるため、パフォーマンスにある程度影響します。この設定を使用する場合は、接続を使用するユーザーごとに ConnectionGroupName を指定する必要もあります。

<channel ref="http client" unsafeAuthenticatedConnectionSharing="false" >

この機能は、.NET Framework のバージョン 1.1 で HttpChannel を使用している場合にのみ利用できます。

認証された接続の使用を制御する

unsafeAuthenticationConnectionSharing を true に設定している場合は、connectionGroupName プロパティを設定して、認証された接続をグループ化するための名前を指定する必要があります。既定の資格情報を使用している場合、connectionGroupName はスレッドの実行に使用されるユーザー アカウントに基づきます。

<channel ref="http client" connectiongroupname="<name>" />

カスタム プロセスによるホスティング

Windows サービス ホストと TcpChannel を使用している場合、このアプローチは信頼されたサーバー シナリオだけで使用するか、カスタムの認証スキームを提供します。カスタム ホストを TcpChannel と共に使用する場合には、次のガイドラインが適用されます。

ネットワーク上でプレーンテキストの資格情報を渡しません。

クライアントから渡される IPrincipal オブジェクトを信頼しません。

ネットワーク上でプレーンテキストの資格情報を渡さない

サーバーにクライアントのプレーンテキストの資格情報が必要な場合は、その資格情報を暗号化してから、ネットワークで送ります。サーバーがクライアントの資格情報を検証する必要がある場合は、チャレンジ/レスポンス スキームを使用してサーバーで資格情報を検証します。これは、ハッシュ、キー ハッシュ、ハッシュで暗号化された nonce を送信するか、またはデジタル署名を使用して実行できます。

ただし、これらのシナリオでも、リプレイ攻撃を防ぐために暗号化された通信チャネルを使用する必要があります。

クライアントから渡された IPrincipal オブジェクトは信頼しない

クライアントからサーバーに IPrincipal オブジェクトを渡す場合には注意が必要です。信頼されていないコードは、IPrincipal オブジェクトを作成して、ロールでそのオブジェクトを初期化してから、サーバーに送る可能性があります。サーバーが検証なしに IPrincipal を受け取る場合、クライアントはサーバーの呼び出し側の権限を格上げしてしまう可能性があります。たとえば、悪質な呼び出し側は、共通の高度な権限ロール名 (Administrators、Managers、ExpenseReportApprovers、Supervisors など) を含む IPrincipal オブジェクトを作成する可能性があります。このオブジェクトがサーバーでを受け取られ、Thread.CurrentPrincipal プロパティに置かれると、このオブジェクトの IsInRole を呼び出すコードが侵入して権限を持つコードを実行してしまう場合があります。

承認

.NET Framework Remoting のコンテキストでは、承認を適用して、リモート オブジェクトで公開される機能へのコンピュータおよびユーザーのアクセスを制限することができます。効果的な承認アプローチを実行するためには、次のガイドラインを使用します。

マシン レベルのアクセス制御には IPSec を使用します。

ユーザーのアクセス制御に対してファイル承認を有効にします。

プリンシパルベースのロール チェックでユーザーを承認します。

リモート アクセスの制限を検討します。

マシン レベルのアクセス制御には IPSec を使用する

指定された Web サーバーまたはサーバーのクラスタだけが、リモート オブジェクトをホストするアプリケーション サーバーに接続できるようにするには、IPSec ポリシーを定義します。これにより、攻撃を受ける領域を大幅に減らすことができます。

ユーザー アクセス制御に対するファイル承認を有効にする

ASP.NET でリモート オブジェクトをホストし、Windows 認証を使用している場合は、Remoting エンドポイントに Windows アクセス制御リスト (ACL) を設定して、呼び出し側を承認できます。ACL は、ASP.NET の FileAuthorizationModule によって要求単位で評価されます。通常の状況では、クライアントの接続先となる Remoting エンドポイントを表す物理ファイルは存在しません。IIS で、IIS Metabase で定義されたアプリケーション マッピングに基づいて、適切な ASP.NET アプリケーション内の .NET Remoting インフラストラクチャに要求をルーティングできるようにするには、.rem または .soap の拡張子が付いたファイルが必要です。

ASP.NET の FileAuthorizationModule を .NET Framework Remoting 用に設定するには

1.

Web.config の objectUri プロパティで指定した値と同じ名前 (この例では、RemoteMath.rem) のファイルを、アプリケーションの仮想ディレクトリのルートに作成します。
objectUri は、サーバーでリモート オブジェクトを設定するために使用する Web.config ファイルから取得できます。次の例に示されるような <wellknown> 要素を探します。

<wellknown mode="SingleCall" objectUri="RemoteMath.rem" 
type="RemotingObjects.RemoteMath, RemotingObjects, 
Version=1.0.000.000 Culture=neutral, PublicKeyToken=4b5ae668c251b606"/>

2.

ファイルの先頭に次の行を追加し、ファイルを保存します。

<%@ webservice class="YourNamespace.YourClass" ... %>

3.

エクスプローラで、適切に設定された ACL をファイルに追加し、オブジェクトにアクセスできるユーザーまたはユーザー グループ、およびオブジェクトにアクセスできないユーザーまたはユーザー グループを決定します。

プリンシパルベースのロール チェックでユーザーを承認する

前に説明した FileAuthorizationModule アプローチでは、リモート オブジェクトにアクセスできるユーザーとアクセスできないユーザーを制御できます。メソッド レベルで適用できる、さらにきめの細かい承認を行う場合は、現在の要求に関連付けられた IPrincipal オブジェクトを使用して承認チェックを実行することができます。

リモート オブジェクトを ASP.NET でホストし、Windows 認証を使用している場合は、認証された呼び出し側の Windows 識別情報に基づいて IPrincipal オブジェクトが自動的に作成され、Thread.CurrentPrinicipal に関連付けられます。

カスタム ホストを使用している場合は、認証されているユーザーを表す IPrincipal オブジェクトを作成します。方法は、認証アプローチによって異なります。たとえば、名前付きパイプ トランスポートを使用している場合は、呼び出し側を偽造して、その識別情報を取得し、IPrincipal オブジェクトを作成することができます。

適切な IPrincipal オブジェクトを使用すると、主要なアクセス許可要求を使用して宣言および偽造の両方によって承認を実行し、IPrincipal.IsInRole を呼び出すことができます。

リモート アクセスの制限を検討する

1 台のコンピュータでの内部プロセスやクロス アプリケーション ドメイン通信に Remoting を使用する場合には、次に示すように rejectRemoteRequests を true に設定して、オブジェクトがリモート コンピュータからアクセスできないようにすることができます。

<channel ref="http server" rejectRemoteRequests="true" />

機密性の高いデータ

ネットワーク上でリモートの通信チャネルを介して機密性の高いデータを受け渡す必要がある場合は、ネットワーク盗聴の脅威を解決するために、データのプライバシと完全性を考慮します。使用している展開環境と選択したホストによって決定する 3 つの基本的な選択肢が用意されています。次の中から選択できます。

IPSec を使用します。

SSL を使用します。

カスタム暗号化シンクを使用します。

IPSec を使用する

リモート オブジェクトへの通信チャネル (Web サーバーからのチャネル) を保護する場合には、IPSec ポリシーを使用できます。IPSec を使用して、特定の接続で送信される TCP パケット (リモート オブジェクト間でやりとりされるパケットを含む) をすべて暗号化できます。通常、このソリューションは、セキュリティ保護されたインターネットおよびイントラネット データ センター インフラストラクチャで使用され、コードを追加する必要がないので便利です。

また、IPSec を使用すると、リモート オブジェクト ホストとチャネル タイプに関係なく、セキュリティ保護された通信ソリューションを利用できるという利点もあります。たとえば、TcpChannel とカスタム ホストを使用している場合にこのソリューションを利用できます。

SSL を使用する

ASP.NET ホストを使用する場合は、IIS を使用して、SSL が必要なアプリケーションの仮想ディレクトリを設定します。その後、クライアントは HTTPS 接続を使用してリモート オブジェクトと通信する必要があります。

カスタム暗号化シンクを使用する

サーバー間の通信チャネルを保護する IPSec ポリシーを使用するセキュリティ保護されたデータ センターを使用していない場合は、代わりにカスタムの暗号化シンクを実装することができます。ペイロード全体ではなく、クライアントとサーバー間でやりとりされるメッセージの機密性の高い部分だけを保護する必要がある場合にも、このオプションを使用できます。このアプローチを図 13.4 に示します。

カスタム暗号化シンクを使用する

図 13.4
カスタム暗号化シンクを使用する

暗号化シンクとは、カスタム ホストと TcpChannel を併用する場合に使用できるカスタムのチャネル シンクです。クライアント側では、シンクは要求データを暗号化してからサーバーに送り、サーバーから受信した、暗号化された応答データを解読します。サーバー側では、シンクは要求データを解読してから、応答データを暗号化します。

カスタム暗号化シンクを実装する

シンクでは、非対称の暗号化を使用してセッション レベルの暗号化キーを交換します。セッション キーの交換後、クライアントとサーバーはキーのコピーを維持し、チャネル シンクの有効期間中の任意の時点でクライアントとサーバーのどちらかが新しいキーを作成できます。サーバーは通信するクライアントごとに別のキーを保持する必要があります。

次の手順で、カスタム暗号化シンクを実装するための基本的なアプローチの概要を説明します。

1.

ソリューションの公開/秘密キー ペアを作成します。

const int AT_KEYEXCHANGE =  1;
CspParameters cspParams = new CspParameters();
cspParams.KeyContainerName = "<container name>";
cspParams.KeyNumber = AT_KEYEXCHANGE;
cspParams.ProviderName = "Microsoft Base Cryptographic Provider v1.0";
cspParams.ProviderType = PROV_RSA_FULL;
RSACryptoServiceProvider rsaServerSide = new 
RSACryptoServiceProvider(cspParams);
rsaServerSide.PersistKeyInCsp = true;
Console.WriteLine(rsaServerSide.ToXmlString(true)); // Writes the public key

2.

クライアントが使用できるように公開キーを公開します。
クライアントはファイルに公開キーのコピーを保持します。

3.

クライアントのチャネル シンクを初期化し、暗号化用のランダム キーを作成します。

byte[] randomKey = new byte[size];
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
rng.GetBytes(randomKey);

4.

サーバーの公開キーでランダム キーを暗号化します。IClientChannelSink.ProcessMessage を使用して、暗号化キーをサーバーに送信します。

RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(csp);
rsa.FromXmlString("<server's public key>");
AsymmetricKeyExchangeFormatter formatter = new 
RSAPKCS1KeyExchangeFormatter(rsa);
byte[] encryptedSessionKey =  formatter.CreateKeyExchange(_sessionKey);

5.

サーバーのチャネル シンクを初期化し、特定のキー コンテナ名を使用して RSA オブジェクトを作成します。

const int AT_KEYEXCHANGE =  1;
CspParameters cspParams = new CspParameters();
cspParams.KeyContainerName = "<container name>";
cspParams.KeyNumber = AT_KEYEXCHANGE;
cspParams.ProviderName = "Microsoft Base Cryptographic Provider v1.0";
cspParams.ProviderType = PROV_RSA_FULL;
RSACryptoServiceProvider rsaServerSide = new 
RSACryptoServiceProvider(cspParams);

6.

クライアントから暗号化されたキーを取得します。通常、このキーは要求ヘッダーで送信されます。

7.

サーバーの秘密キーを使用してセッションの暗号化キーを解読します。

AsymmetricKeyExchangeDeformatter asymDeformatter = new 
RSAPKCS1KeyExchangeDeformatter(_rsa);
byte[] decryptedSessionKey =  asymDeformatter.DecryptKeyExchange(
<encrypted key>);

8.

クライアントを暗号化キーにマップするメカニズム (ハッシュ テーブルを使用するなど) を使用します。

この時点で、クライアントとサーバーの両方が暗号化キーを共有し、メソッドの呼び出しを暗号化および解読できるようになります。オブジェクトの有効期間中、定期的に新しいキーを作成する必要があります。

サービス拒否

サービス拒否 (DoS) 攻撃は、悪質なクライアントが複数のオブジェクトを作成し、有効期限リースを継続的に更新して、サーバーのリソースを消耗させる場合に発生する可能があります。サーバー側のリモート オブジェクトには既定のリースが含まれています。この場合、クライアントはリースを永遠に更新し続ける可能性があります。ただし、ILease インターフェイスをサーバーに実装して、スポンサーと更新を明示的に制御することができます。これを行うためには、MarshalByRefObject オブジェクトの InitializeLifetimeService を上書きします。.NET Remoting インフラストラクチャは、オブジェクトが作成されると、このメソッドを呼び出します。リースは、<lifetime> 要素を使用してプログラムによって設定することもできます。

例外管理

呼び出し側には完全な例外詳細を返さないようにする必要があります。ASP.NET ホストを使用する場合は、次に示すように、一般的なエラー メッセージがクライアントに返されるようにASP.NET を設定してください。

<configuration>
<system.runtime.remoting>
<!-- mode 属性の有効な値は次のとおりです。
on - 呼び出し側は既定のエラー メッセージを受け取ります。
remoteOnly - リモート コンポーネントと同じコンピュータ上のクライアントは
詳細な例外情報を受け取ります。リモートの呼び出しは既定の 
エラー メッセージを受け取ります。 
off - 呼び出し側は詳細な例外情報を受け取ります。 -->
<customErrors mode="on"/>
<system.runtime.remoting>
</configuration>

mode="on" または mode="remoteOnly" を使用します。mode="off" は運用サーバーでは使用しないでください。

カスタム暗号化シンクを使用する

カスタムのチャネル シンクを実装して、クライアント側とサーバー側で例外ロギングを実行できます。例外が発生すると、SyncProcessMessage、ProcessMessage、または SyncProcessMessage メソッドに例外の詳細が記録されます。IMessage パラメータと Exception パラメータは例外の詳細を提供します。

監査とログ記録

ASP.NET ホストを使用している場合は、IIS の監査機能を使用できます。カスタム ホストを使用している場合は、カスタムの監査機能を実装します。これを行うには、カスタムのチャネル シンクを実装します。

カスタム暗号化シンクを使用する

カスタムのチャネル シンクを実装して、クライアント側とサーバー側で監査機能を実行できます。SyncProcessMessage、ProcessMessage または SyncProcessMessage メソッドから詳細を取得できます。

コード アクセス セキュリティ (CAS) に関する考慮事項

.NET Framework バージョン 1.0 および 1.1 では、Remoting クライアントに完全信頼が要求されます。System.Runtime.Remoting.dll アセンブリは、AllowPartiallyTrustedCallersAttribute でマークされていません。

Remoting を使用して部分的に信頼されているコード (部分的に信頼されている Web アプリケーションなど) からリモート コンポーネントを呼び出すには、完全信頼のラッパー アセンブリを作成し、リモート オブジェクトのメソッド呼び出しをサンドボックス化します。コードのサンドボックス化およびラッパー アセンブリの使用の詳細については、モジュール 9 「ASP.NET でコード アクセス セキュリティを使用する」を参照してください。

要約

.NET Framework Remoting インフラストラクチャでは、IPSec セキュリティ ポリシーの使用などにより、信頼されたサーバー シナリオで呼び出し側を信頼されたクライアントに制限することができます。ASP.NET ホストと HttpChannel を併用する場合は、ASP.NET と IIS の基底のセキュリティ機能を使用することができます。カスタム ホストと TcpChannel を使用している場合は、パフォーマンス上の理由から、独自の認証および承認ソリューションを実装する必要があります。IPSec は、マシン レベルの認証およびセキュリティ保護された通信を提供することでこれらのシナリオをサポートします。

その他のリソース

詳細については、次のリソースを参照してください。

印刷可能なチェックリストについては、このガイドの「チェクリスト」にある「チェックリスト: Remoting をセキュリティ保護する」を参照してください。

Web Services でのクライアント証明書の使い方については、Microsoft patterns & practices「セキュリティ保護された ASP.NET アプリケーションの構築: 認証、認定、および通信のセキュリティ保護」の「Windows サービスでリモート オブジェクトをホストする方法」(http://www.microsoft.com/japan/msdn/net/security/SecNetHT15.asp) を参照してください。

SSPI を使用するカスタムの認証ソリューションの作成方法の詳細については、MSDN 記事「.NET Remoting Security Solution, Part 1: Microsoft.Samples.Security.SSPI Assembly」(英語) (http://msdn.microsoft.com/library/en-us/dndotnet/html/remsspi.asp) を参照してください。

注: この文書で取り上げている実装はサンプルであり、Microsoft によってテストおよびサポートされている製品ではありません。


© 2008 Microsoft Corporation.All rights reserved. 使用条件  |  商標  |  プライバシー
Page view tracker