flawopen.com/XXE/.NET XML 解析器
.NET 中的 XmlReader 能防御 XXE 吗?
可以把 DTD 想成允许解析器获取 XML 中所命名文档的通行证。XmlReader.Create 默认拒绝 DTD,因此除非应用启用它,不可信文档无法走这条路径。旧 API 和目标框架版本也很重要:应明确禁止 DTD,并在解析边界关闭外部资源解析。
// 直接使用旧 reader 时可能启用 DTD 解析 // 外部 resolver 会获取 XML 中引用的资源。 var legacy = new XmlTextReader(stream) { DtdProcessing = DtdProcessing.Parse, XmlResolver = new XmlUrlResolver() }; while (legacy.Read()) { } // 对不可信 XML 显式启用 DTD 存在风险: var unsafeSettings = new XmlReaderSettings { DtdProcessing = DtdProcessing.Parse, XmlResolver = new XmlUrlResolver() }; using var reader = XmlReader.Create(stream, unsafeSettings);
var settings = new XmlReaderSettings {
// 拒绝任何包含 DTD 的文档。
DtdProcessing = DtdProcessing.Prohibit,
// 纵深防御:不获取外部资源。
XmlResolver = null,
// 根据应用的合法输入选择限制值。
MaxCharactersInDocument = 1_000_000,
MaxCharactersFromEntities = 1_024,
};
using var reader = XmlReader.Create(stream, settings);
var doc = new XmlDocument { XmlResolver = null };
doc.Load(reader);
你使用的是哪种 XML API 和 .NET 版本?
.NET has several XML APIs whose defaults have differed, and whose defaults have also changed across framework versions. The practical summary:
- ✓默认配置的 XmlReader.Create — 默认值是 DtdProcessing.Prohibit。在不可信输入边界显式设置,避免之后修改配置时意外启用 DTD。
- ✓XmlReaderSettings.XmlResolver — .NET Framework 4.5.2 将默认值改为 null;更早版本可能使用 XmlUrlResolver。应显式设为 null,并检查兼容开关 EnableLegacyXmlSettings。
- ✓XmlTextReader — 直接使用此旧 API 时默认行为不同,且可能解析 DTD。优先使用显式配置的 XmlReader.Create;不要为不可信 XML 配置网络或文件 resolver。
- ✓XmlDocument 和 LINQ to XML — 行为取决于加载方式和目标框架。应传入加固后的 XmlReader,并将可用的 resolver 设为 null。
.NET Framework 4.5.2 将 XmlReaderSettings.XmlResolver 的默认值设为 null,并将 MaxCharactersFromEntities 初始化为 1000 万;但这并不意味着所有 XML API 或配置都相同。兼容开关可能恢复旧默认值。应显式设置解析器策略、限制文档大小,并检查实际目标框架和运行时配置。
常见问题
是。XmlReaderSettings.DtdProcessing 默认值为 Prohibit,遇到 DTD 时会抛出异常。仍建议显式设置,并将 XmlResolver 设为 null 作为纵深防御。
出于安全考虑,XmlReaderSettings.XmlResolver 默认改为 null,MaxCharactersFromEntities 初始化为 1000 万。EnableLegacyXmlSettings 可恢复旧行为;应检查部署配置,而不只是目标框架。
可能会。这些格式包含 XML,但具体影响取决于解析器和配置。确保每个不可信 XML 入口都使用加固后的 reader,限制输入大小,并遵循相应格式库的安全指南。