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.CreateXmlReader インスタンスを作成するために推奨される方法ですが、XmlTextReader とは異なる動作をします。 Create からのXmlReader は、XML 値内で \r\n\n に正規化しますが、XmlTextReader\r\n シーケンスを保持します。