必须禁用DTD和外部实体解析以防止XXE攻击:设置DtdProcessing.Prohibit(.NET Core/.NET 5+)或ProhibitDtd=true(.NET Framework),并设XmlResolver=null;同时限制输入长度、深度等,避免使用不安全的Load()方法。
在C#中使用 XmlReader 解析XML时,若未正确配置 XmlReaderSettings,可能遭受XML外部实体(XXE)攻击。关键在于禁用外部实体解析和DTD处理。
默认情况下,XmlReader 可能加载并解析DTD(文档类型定义)及外部实体(如 ),导致敏感文件读取或SSRF。必须显式关闭这些功能:
ProhibitDtd = true(.NET Framework 4.0+)或 DtdProcessing = DtdProcessing.Prohibit(.NET Core/.NET 5+)XmlResolver = null,防止解析任何外部URI(包括系统标识符、实体引用)以下是最小安全配置(适用于 .NET Core 3.1+ 和 .NET 5+):
var settings = new XmlReaderSettings
{
DtdProcessing = DtdProcessing.Prohibit,
XmlResolver = null,
ValidationType = ValidationType.None // 禁用验证以避免隐式加载schema
};
using var reader = XmlReader.Create(xmlStream, settings);
// 后续调用 Read() 解析
对于 .NET Framework 4.0–4.7.x,改用:
var settings = new XmlReaderSettings
{
ProhibitDtd = true,
XmlResolver = null,
ValidationType = ValidationType.None
};
仅靠禁用DTD还不够,还需注意以下实践:
MaxCharactersInDocument、MaxCharactersFromEntities)XmlDocument.Load() 或 XDocument.Load() 直接解析不受控XML,它们默认启用DTD且不易安全配置LineNumberOffset = 0、LinePositionOffset = 0,但非安全必需项构造一个含外部实体的测试XML(如 ]>),用上述设置解析——若抛出 XmlException(提示“prohibited”或“
DTD is prohibited”),说明防护已起效;若成功加载或静默失败,则配置有误。