System.Xml のセキュリティに関する考慮事項

更新 : November 2007

以下のセクションでは、System.Xml コンポーネントの使用時に生じる可能性のあるセキュリティ上の問題の種類と、それらの脅威を軽減するためにできることについて説明します。

メモ :

System.Xml のコンポーネントは、Microsoft .NET Framework のセキュリティ システムに依存しています。このトピックでは、XML クラスによって処理されるセキュリティ上の問題だけを対象にしています。詳細については、「.NET Framework におけるセキュリティ」を参照してください。

  • XmlResolver クラス

  • XmlReader および XmlReaderSettings クラス

  • XmlTextReader クラス

  • XslCompiledTransform クラス

  • Document Object Model

XmlResolver クラス

XmlResolver クラスはリソースの解決に使用されます。これは、XML ドキュメントの読み込みと、エンティティ、DTD またはスキーマ、import または include ディレクティブなど、外部リソースの解決に使用されます。.NET Framework には XmlResolver クラスの 2 つの実装が含まれています。

XmlUrlResolver クラスは、System.Xml 名前空間内のクラスすべての既定のリゾルバです。これは、file:// および http:// プロトコルをサポートし、WebRequest クラスからの要求をサポートします。多くの場合、アプリケーションが使用する XmlResolver オブジェクトを指定しないと、XmlUrlResolver オブジェクトがユーザー資格情報なしで XML リソースのアクセスに使用されます。

XmlSecureResolver クラスは、XmlResolver オブジェクトをラップして元の XmlResolver がアクセスできるリソースを制限することにより、別の XmlResolver オブジェクトを安全に保つように支援します。たとえば、XmlSecureResolver クラスは、特定のインターネット サイトやゾーンへのアクセスを禁止できます。

XmlResolver クラスを使用する際には、次の事項を考慮する必要があります。

  • XmlResolver オブジェクトは、データにアクセスしてデータを読み取るために使用できるユーザー資格情報など、重要な情報を含む場合があります。信頼できないコンポーネントが XmlResolver とそのユーザー資格情報を使用してデータにアクセスできる場合があるので、XmlResolver オブジェクトをキャッシュする場合は注意が必要であり、XmlResolver オブジェクトを信頼できないコンポーネントに渡さないようにする必要があります。

  • XmlResolver クラスを使用したクラス プロパティを設計する場合は、そのプロパティは書き込み専用として定義する必要があります。使用する XmlResolver を指定するためにそのプロパティを使用できますが、XmlResolver オブジェクトを返すためには使用できません。これで信頼できないコンポーネントはクラスを使用できますが、XmlResolver オブジェクトを取得して直接使用することは許可されていません。

  • アプリケーションが信頼できないコードから XmlResolver オブジェクトを受け入れる場合、GetEntity メソッドに渡した URI が ResolveUri メソッドから返された URI と同一であると仮定することはできません。XmlResolver クラスから派生したクラスは、GetEntity メソッドをオーバーライドすることができ、元の URI に含まれていたデータと異なるデータを返すことができます。

  • アプリケーションは、ラップを実装して読み込むバイト数を制限した IStream を実装することにより、GetEntity メソッドに対するメモリのサービス不能の脅威を軽減することができます。これは、悪意のあるコードが GetEntity メソッドに対して無限のバイト ストリームを渡そうとした場合に対抗する保護策として役立ちます。

XmlReader および XmlReaderSettings クラス

実質的に、すべての System.Xml コンポーネントは、XML の解析という考えの上に構築されています。たとえば、XmlDocument クラスは、XmlReader クラスを使用してドキュメントを解析し、XML ドキュメントのメモリ内表現を構築します。

XmlReader オブジェクトの作成には、Create メソッドの使用が推奨されます。XmlReaderSettings クラスを使用して、XmlReader オブジェクトで使用する機能を指定します。

ドキュメントとエンティティの拡張サイズの制限

XmlReader を使用するアプリケーションのメモリ使用量が、解析済み XML ドキュメントのサイズに相関する場合があります。非常に大きな XML ドキュメントを送信して解析させることは、サービス拒否攻撃 (DoS) の一種です。

XmlReader を使用するときには、MaxCharactersInDocument プロパティを設定することで、解析可能なドキュメントのサイズを制限できます。エンティティの展開により生成される文字数を制限するには、MaxCharactersFromEntities プロパティを設定します。これらのプロパティの設定例については、該当するトピックを参照してください。

DTD 処理

DTD の処理が DoS 状態に陥ることがあります。たとえば、DTD に、処理に過度の時間を要する入れ子のエンティティや複合コンテンツ モデルが含まれることがあります。

既定で DTD の処理は無効になっています。XmlReader が DTD データに到達すると、XmlException がスローされます。

スキーマ処理

XmlReaderSettings オブジェクトの ProcessInlineSchema および ProcessSchemaLocation の検証フラグは、既定では設定されていません。このことは、信頼できないソースからの XML データを処理する際に、スキーマ ベースの攻撃から XmlReader を保護するのに役立ちます。これらのフラグが設定されていると、XmlReaderSettings オブジェクトの XmlResolverXmlReader のインスタンス ドキュメント中に出現したスキーマの場所を解決するために使用されます。XmlResolver プロパティが null に設定されている場合は、たとえ ProcessInlineSchema および ProcessSchemaLocation の検証フラグが設定されていても、スキーマの場所は解決されません。

検証中に追加されたスキーマは新しい型を追加し、検証中のドキュメントの検証結果を変えてしまうことがあります。結果として、信頼できるソースからの外部スキーマだけが解決されるようにする必要があります。

高可用性が必要なシナリオで、信頼できない大きな XML ドキュメントの大きな部分を ID 制約のあるスキーマに対して検証する際には、ProcessIdentityConstraints フラグ (既定で有効) は無効にすることが推奨されます。

外部リソース

XML データには、スキーマ ファイルなど、外部リソースへの参照が含まれることがあります。既定では、外部リソースはユーザー資格情報なしで、XmlUrlResolver オブジェクトを使用して解決されます。これは、資格情報を必要としない任意の場所に既定でアクセスできることを意味します。次の対策により、これをさらに安全にすることができます。

XmlReaderSettings オブジェクトの共有

XmlReaderSettings オブジェクトはユーザー資格情報など、重要な情報を含むことがあります。信頼できないコンポーネントが XmlReaderSettings オブジェクトとそのユーザー資格情報を使用して、XmlReader オブジェクトを作成し、データを読む可能性があります。XmlReaderSettings オブジェクトをキャッシュしたり、XmlReaderSettings オブジェクトをあるコンポーネントから別のコンポーネントに渡したりする場合には注意が必要です。

サポート コンポーネント

  • 信頼できないソースからの NameTableXmlNamespaceManager、および XmlResolver オブジェクトなどのサポート コンポーネントは受け入れないようにします。

データ処理

XML データには、処理に長時間を要する大量の属性、名前空間宣言、入れ子になった要素などが含まれることがあります。

  • 使用する入力サイズを制限したカスタム IStream 実装を作成して、それを XmlReader クラスに供給することができます。

  • 大きなデータ ストリームを取り扱うには、ReadValueChunk メソッドを使用します。このメソッドは、値全体に 1 つの文字列を割り当てる代わりに、一度に少数の文字を読みます。

XmlTextReader クラス

XmlTextReader クラスは XmlReader クラスの古い実装です。

DTD 処理

DTD の処理は既定で有効になっています。DTD の処理を無効にするには、ProhibitDtd プロパティを true に設定します。

エンティティの処理

既定では、一般エンティティは展開されません。一般エンティティは ResolveEntity メソッドを呼び出したときに展開されます。

外部リソース

XML データには、DTD 参照など、外部リソースへの参照が含まれることがあります。既定では、外部リソースはユーザー資格情報なしで、XmlUrlResolver オブジェクトを使用して解決されます。

次の対策により、これをさらに安全にすることができます。

XslCompiledTransform クラス

XslCompiledTransform クラスは、XSLT 1.0 構文をサポートする XSLT プロセッサです。これにより、XSLT スタイルシートを使用した XML データの変換が可能となります。

外部リソース

スタイル シートには、xsl:import 要素、xsl:include、document() 関数など、外部リソースへの参照を含めることができます。

XslCompiledTransform クラスは xsl:import 要素や xsl:include 要素を既定でサポートします。XslCompiledTransform クラスは document() 関数のサポートを既定で無効にします。document() 関数を有効にするには、XsltSettings クラスを使用します。

Load メソッドおよび Transform メソッドには、XmlResolver オブジェクトを引数の 1 つとして受け取るオーバーロードが含まれます。XmlResolver を指定しない場合は、資格情報を持たない既定の XmlUrlResolver が使用されます。

外部リソースのアクセス方法は、次を行うことによって制御できます。

  • XmlSecureResolver オブジェクトを使用して、XSLT プロセッサがアクセスできるリソースを制限する。

  • XmlResolver の引数に null を渡して、XSLT プロセスが外部リソースを開けないようにする。

スクリプト ブロック

XslCompiledTransform クラスは、既定ではスクリプト ブロックをサポートしません。スクリプト ブロックは、XsltSettings クラスを使用して有効にします。XSLT スクリプトは、スクリプトのサポートが必要であり、完全に信頼された環境で作業している場合のみ有効にします。

拡張オブジェクト

拡張オブジェクトは XSLT 変換に対するプログラム機能です。この機能は、既定で有効になっています。拡張オブジェクトが Transform メソッドに渡されると、それらが XSLT 変換で使用されます。

ドキュメント オブジェクト モデル

ドキュメント オブジェクト モデル (DOM) はすべてのデータをメモリにキャッシュするので、信頼できないデータを使用していて、DoS 攻撃が懸念される場合、クエリ、編集、サブツリーのドキュメント間の移動、DOM オブジェクトの保存などの DOM 操作は推奨されません。もう 1 つの方法は、DOM に読み込むデータ量に制限を設定することです。これを行う 1 つの方法は、使用する入力のサイズを制限するカスタム ストリームの実装を作成し、これを使用して DOM オブジェクトを読み込むことです。

XmlDocument オブジェクトは、埋め込みの XmlResolver オブジェクトに、ユーザー資格情報などの重要な情報を含むことがあります。XmlResolver オブジェクトに、XmlDocument.XmlResolver プロパティがユーザー資格情報と共に設定されている場合、XmlDocument オブジェクトをキャッシュしたり、それを信頼できないコンポーネントに渡さないようにしたりする必要があります。信頼できないコンポーネントが DOM オブジェクトと埋め込まれた XmlResolver のユーザー資格情報を使用して、データにアクセスして読み込む可能性があります。

参照

概念

System.Xml のコーディング ガイドライン