如何在 C# 中配置 XML 解析器以禁用外部实体解析
Posted
技术标签:
【中文标题】如何在 C# 中配置 XML 解析器以禁用外部实体解析【英文标题】:How to configure the XML parser to disable external entity resolution in c# 【发布时间】:2015-11-19 02:23:50 【问题描述】:var xDoc = XDocument.Load(fileName);
我在函数中使用上述代码来加载 XML 文件。功能方面它工作正常,但在 Veracode 检查后显示以下 Veracode 缺陷。
说明
产品处理的 XML 文档可以包含 XML 实体,其 URL 可解析为外部文档 超出预期的控制范围,导致产品在其输出中嵌入不正确的文档。默认情况下, XML 实体解析器将尝试解析和检索外部引用。如果攻击者控制的 XML 可以 提交给这些函数之一,然后攻击者可以访问有关内部网络的信息,本地 文件系统或其他敏感数据。这称为 XML 外部实体 (XXE) 攻击。
建议
配置 XML 解析器以禁用外部实体解析。
我需要做些什么来解决它。
【问题讨论】:
【参考方案1】:如果您没有在 XML 中使用外部实体引用,则可以通过将解析器设置为 null 来禁用解析器,来自 How to prevent XXE attack ( XmlDocument in .net)
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.XmlResolver = null;
xmlDoc.LoadXml(OurOutputXMLString);
如果您希望文档包含实体引用,那么您需要创建一个自定义解析器并将您期望的内容列入白名单。 特别是,对您无法控制的网站的任何引用。
【讨论】:
【参考方案2】:实现自定义XmlResolver
并将其用于读取XML。默认使用XmlUrlResolver
,它会自动下载解析的引用。
public class CustomResolver : XmlUrlResolver
public override object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn)
// base calls XmlUrlResolver.DownloadManager.GetStream(...) here
并像这样使用它:
var settings = new XmlReaderSettings XmlResolver = new CustomResolver() ;
var reader = XmlReader.Create(fileName, settings);
var xDoc = XDocument.Load(reader);
【讨论】:
我在 windows 项目中使用此代码。有什么区别吗? GetEntity() 方法的内部是什么? @gene:通常您应该返回一个包含 DTD 或其他外部源的流。例如,如果您有一个像<!DOCTYPE myxml SYSTEM "MyDTD.dtd">
这样的文档类型,则使用 absoluteUri == "MyDTD.dtd"
调用 GetEntity
,您应该返回一个包含其内容的流。您可以简单地返回一个空的 DTD,这样 DTD 中定义的实体将保持未解析。
我已完成此操作并在 Veracode 中执行了重新扫描,但我遇到了同样的问题。知道为什么吗?【参考方案3】:
根据 OWASP 官方文档,您需要这样做:
使用 XercesDOMParser 这样做是为了防止 XXE:
XercesDOMParser *parser = new XercesDOMParser;
parser->setCreateEntityReferenceNodes(false);
使用 SAXParser,这样做是为了防止 XXE:
SAXParser* parser = new SAXParser;
parser->setDisableDefaultEntityResolution(true);
使用SAX2XMLReader,这样做是为了防止XXE:
SAX2XMLReader* reader = XMLReaderFactory::createXMLReader();
parser->setFeature(XMLUni::fgXercesDisableDefaultEntityResolution, true);
看看这些指南:https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
【讨论】:
【参考方案4】:你可以试试这个方法:
XmlDocument doc = new XmlDocument() XmlResolver = null ;
System.IO.StringReader sreader = new System.IO.StringReader(fileName);
XmlReader reader = XmlReader.Create(sreader, new XmlReaderSettings() XmlResolver = null );
doc.Load(reader);
【讨论】:
以上是关于如何在 C# 中配置 XML 解析器以禁用外部实体解析的主要内容,如果未能解决你的问题,请参考以下文章
如何使用com.sun.org.apache.xerces.internal.parsers.SAXParser在SAXBuilder中禁用XML外部实体(XEE)处理