CA3075:不安全的 DTD 处理

属性
规则 ID CA3075
标题 不安全的 DTD 处理
类别 安全性
修复是中断修复还是非中断修复 非中断
在 .NET 8 中默认启用

原因

如果使用不安全的 DtdProcessing 实例或引用外部实体源,分析器可能会接受不受信任的输入并将敏感信息泄露给攻击者。

规则说明

XML 分析器可以通过两种方式确定文档有效性,文档类型定义 (DTD) 是其中一种(根据万维网联合会 (W3C) 可扩展标记语言 (XML) 1.0 的定义)。 此规则会查找接受不受信任数据的属性和实例,以提醒开发人员潜在的信息泄漏威胁或拒绝服务 (DoS) 攻击。 在以下情况下触发此规则:

在这些情况下,结果均相同:来自文件系统或来自处理 XML 的计算机的网络共享的文件都将面临攻击,或 DTD 处理可用作 DoS 向量。

如何解决冲突

.NET Framework 3.5 及更早版本

  • 如果正在处理不可信的源,请通过将 ProhibitDtd 属性设置为“true”来禁用 DTD 处理。

  • XmlTextReader 类具有完全信任继承要求。

.NET Framework 4 及更高版本

  • 如果正在处理不可信的源,请通过将 XmlReaderSettings.DtdProcessing 属性设置为“禁止”或“忽略”来避免启用 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 序列。