CA3075:不安全的 DTD 处理
属性 | 值 |
---|---|
规则 ID | CA3075 |
标题 | 不安全的 DTD 处理 |
类别 | 安全性 |
修复是中断修复还是非中断修复 | 非中断 |
在 .NET 8 中默认启用 | 否 |
原因
如果使用不安全的 DtdProcessing 实例或引用外部实体源,分析器可能会接受不受信任的输入并将敏感信息泄露给攻击者。
规则说明
XML 分析器可以通过两种方式确定文档有效性,文档类型定义 (DTD) 是其中一种(根据万维网联合会 (W3C) 可扩展标记语言 (XML) 1.0 的定义)。 此规则会查找接受不受信任数据的属性和实例,以提醒开发人员潜在的信息泄漏威胁或拒绝服务 (DoS) 攻击。 在以下情况下触发此规则:
在 XmlReader 实例上启用了 DtdProcessing,它使用 XmlUrlResolver解析外部 XML 实体。
设置了 XML 中的 InnerXml 属性。
DtdProcessing 属性设置为“分析”。
使用 XmlResolver 而不是 XmlSecureResolver 处理不受信任的输入。
使用不安全的 XmlReaderSettings 实例或根本不使用任何实例调用 XmlReader.Create 方法。
使用不安全的默认设置或值创建 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 属性设置为“禁止”或“忽略”来避免启用 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
序列。