CA3075:安全ではない DTD の処理
プロパティ | 値 |
---|---|
ルール ID | CA3075 |
Title | 安全ではない DTD の処理 |
[カテゴリ] | Security |
修正が中断か中断なしであるか | なし |
.NET 8 では既定で有効 | いいえ |
原因
安全ではない DtdProcessing インスタンスを使用する場合、または外部エンティティ ソースを参照する場合、パーサーは信頼されていない入力を受け入れ、攻撃者に機密情報を漏えいしてしまう可能性があります。
規則の説明
ドキュメント型定義 (DTD) は、W3C (World Wide Web Consortium) の拡張マークアップ言語 (XML) 1.0 で定義されているように、XML パーサーが文書の妥当性を判別する 2 つの方法のうちの 1 つです。 この規則は、信頼されていないデータを受け入れてしまうプロパティとインスタンスを検索し、潜在的な情報漏えいの脅威またはサービス拒否 (DoS) 攻撃について開発者に警告します。 このルールは、次の場合にトリガーされます。
XmlReader を使用して外部 XML エンティティを解決する XmlUrlResolverインスタンスで、DtdProcessing が有効になっている。
XML で InnerXml プロパティが設定されている。
DtdProcessing プロパティが Parse に設定されている。
信頼されていない入力が XmlSecureResolver ではなく XmlResolver を使用して処理される。
XmlReader.Create メソッドが安全ではない XmlReaderSettings インスタンスで呼び出される。またはインスタンスがまったくない。
XmlReader が安全ではない既定の設定または値で作成されている。
これらのケースはいずれも、結果は同じになります。XML を処理するマシンが共有するファイル システム、またはネットワークからのコンテンツが攻撃者にさらされ、DTD 処理が DoS の媒介として使用される可能性があります。
違反の修正方法
パス情報の漏えいを防ぐために、XmlTextReader 例外をすべてキャッチし、適切に処理します。
XmlSecureResolver を使用して、XmlTextReader がアクセスできるリソースを制限します。
XmlReader プロパティを XmlResolver null に設定して、がどの外部リソースも開けないようにします。
DataViewManager.DataViewSettingCollectionString プロパティが信頼できるソースから割り当てられていることを確認します。
.NET Framework 3.5 以前
信頼されていないソースを扱う場合には、ProhibitDtd プロパティを true に設定して、DTD 処理を無効にします。
XmlTextReader クラスには、完全信頼の継承確認要求があります。
.NET Framework 4 以降
信頼されていないソースを扱う場合には、XmlReaderSettings.DtdProcessing プロパティを Prohibit または Ignore に設定して、DtdProcessing を有効にしないようにします。
すべての InnerXml ケースで、Load() メソッドが XmlReader インスタンスを取ることを確認します。
注意
このルールは、有効な XmlSecureResolver インスタンスについて誤検知を報告することがあります。
どのようなときに警告を抑制するか
入力が信頼できるソースからのものとわかっているのでない限り、この警告からのルールを抑制しないでください。
警告を抑制する
単一の違反を抑制するだけの場合は、ソース ファイルにプリプロセッサ ディレクティブを追加して無効にしてから、規則をもう一度有効にします。
#pragma warning disable CA3075
// The code that's violating the rule is on this line.
#pragma warning restore CA3075
ファイル、フォルダー、またはプロジェクトの規則を無効にするには、構成ファイルでその重要度を none
に設定します。
[*.{cs,vb}]
dotnet_diagnostic.CA3075.severity = none
詳細については、「コード分析の警告を抑制する方法」を参照してください。
疑似コードの例
違反 1
using System.IO;
using System.Xml.Schema;
class TestClass
{
public XmlSchema Test
{
get
{
var src = "";
TextReader tr = new StreamReader(src);
XmlSchema schema = XmlSchema.Read(tr, null); // warn
return schema;
}
}
}
解決策 1
using System.IO;
using System.Xml;
using System.Xml.Schema;
class TestClass
{
public XmlSchema Test
{
get
{
var src = "";
TextReader tr = new StreamReader(src);
XmlReader reader = XmlReader.Create(tr, new XmlReaderSettings() { XmlResolver = null });
XmlSchema schema = XmlSchema.Read(reader , null);
return schema;
}
}
}
違反 2
using System.Xml;
namespace TestNamespace
{
public class TestClass
{
public XmlReaderSettings settings = new XmlReaderSettings();
public void TestMethod(string path)
{
var reader = XmlReader.Create(path, settings); // warn
}
}
}
解決策 2
using System.Xml;
namespace TestNamespace
{
public class TestClass
{
public XmlReaderSettings settings = new XmlReaderSettings()
{
DtdProcessing = DtdProcessing.Prohibit
};
public void TestMethod(string path)
{
var reader = XmlReader.Create(path, settings);
}
}
}
違反 3
using System.Xml;
namespace TestNamespace
{
public class DoNotUseSetInnerXml
{
public void TestMethod(string xml)
{
XmlDocument doc = new XmlDocument() { XmlResolver = null };
doc.InnerXml = xml; // warn
}
}
}
using System.Xml;
namespace TestNamespace
{
public class DoNotUseLoadXml
{
public void TestMethod(string xml)
{
XmlDocument doc = new XmlDocument(){ XmlResolver = null };
doc.LoadXml(xml); // warn
}
}
}
解決策 3
using System.Xml;
public static void TestMethod(string xml)
{
XmlDocument doc = new XmlDocument() { XmlResolver = null };
System.IO.StringReader sreader = new System.IO.StringReader(xml);
XmlReader reader = XmlReader.Create(sreader, new XmlReaderSettings() { XmlResolver = null });
doc.Load(reader);
}
違反 4
using System.IO;
using System.Xml;
using System.Xml.Serialization;
namespace TestNamespace
{
public class UseXmlReaderForDeserialize
{
public void TestMethod(Stream stream)
{
XmlSerializer serializer = new XmlSerializer(typeof(UseXmlReaderForDeserialize));
serializer.Deserialize(stream); // warn
}
}
}
解決策 4
using System.IO;
using System.Xml;
using System.Xml.Serialization;
namespace TestNamespace
{
public class UseXmlReaderForDeserialize
{
public void TestMethod(Stream stream)
{
XmlSerializer serializer = new XmlSerializer(typeof(UseXmlReaderForDeserialize));
XmlReader reader = XmlReader.Create(stream, new XmlReaderSettings() { XmlResolver = null });
serializer.Deserialize(reader );
}
}
}
違反 5
using System.Xml;
using System.Xml.XPath;
namespace TestNamespace
{
public class UseXmlReaderForXPathDocument
{
public void TestMethod(string path)
{
XPathDocument doc = new XPathDocument(path); // warn
}
}
}
解決策 5
using System.Xml;
using System.Xml.XPath;
namespace TestNamespace
{
public class UseXmlReaderForXPathDocument
{
public void TestMethod(string path)
{
XmlReader reader = XmlReader.Create(path, new XmlReaderSettings() { XmlResolver = null });
XPathDocument doc = new XPathDocument(reader);
}
}
}
違反 6
using System.Xml;
namespace TestNamespace
{
class TestClass
{
public XmlDocument doc = new XmlDocument() { XmlResolver = new XmlUrlResolver() };
}
}
解決策 6
using System.Xml;
namespace TestNamespace
{
class TestClass
{
public XmlDocument doc = new XmlDocument() { XmlResolver = null }; // or set to a XmlSecureResolver instance
}
}
違反 7
using System.Xml;
namespace TestNamespace
{
class TestClass
{
private static void TestMethod()
{
var reader = XmlTextReader.Create(""doc.xml""); //warn
}
}
}
using System.Xml;
namespace TestNamespace
{
public class TestClass
{
public void TestMethod(string path)
{
try {
XmlTextReader reader = new XmlTextReader(path); // warn
}
catch { throw ; }
finally {}
}
}
}
解決策 7
using System.Xml;
namespace TestNamespace
{
public class TestClass
{
public void TestMethod(string path)
{
XmlReaderSettings settings = new XmlReaderSettings() { XmlResolver = null };
XmlReader reader = XmlReader.Create(path, settings);
}
}
}
注意
XmlReader.Create は XmlReader インスタンスを作成するために推奨される方法ですが、XmlTextReader とは異なる動作をします。 Create からのXmlReader は、XML 値内で \r\n
を \n
に正規化しますが、XmlTextReader は \r\n
シーケンスを保持します。
.NET