问题 .NET:阻止XmlDocument.LoadXml检索DTD


我有以下代码(C#),它需要太长时间,它会抛出异常:

new XmlDocument().
LoadXml("<?xml version='1.0' ?><!DOCTYPE note SYSTEM 'http://someserver/dtd'><note></note>");

我明白为什么会那样做。我的问题是如何让它停止?我不关心DTD验证。我想我可以正则代替它,但我正在寻找更优雅的解决方案。

背景:
实际的XML是从我不拥有的网站收到的。当站点正在进行维护时,它返回带有DOCTYPE的XML,该DOCTYPE指向维护期间不可用的DTD。所以我的服务变得不必要,因为它试图为我需要解析的每个XML获取DTD。

这是异常堆栈:

Unhandled Exception: System.Net.WebException: The remote name could not be resolved: 'someserver'
at System.Net.HttpWebRequest.GetResponse()
at System.Xml.XmlDownloadManager.GetNonFileStream(Uri uri, ICredentials credentials)
at System.Xml.XmlDownloadManager.GetStream(Uri uri, ICredentials credentials)
at System.Xml.XmlUrlResolver.GetEntity(Uri absoluteUri, String role, Type ofObjectToReturn)
at System.Xml.XmlTextReaderImpl.OpenStream(Uri uri)
at System.Xml.XmlTextReaderImpl.DtdParserProxy_PushExternalSubset(String systemId, String publicId)
at System.Xml.XmlTextReaderImpl.DtdParserProxy.System.Xml.IDtdParserAdapter.PushExternalSubset(String systemId, String publicId)
at System.Xml.DtdParser.ParseExternalSubset()
at System.Xml.DtdParser.ParseInDocumentDtd(Boolean saveInternalSubset)
at System.Xml.DtdParser.Parse(Boolean saveInternalSubset)
at System.Xml.XmlTextReaderImpl.DtdParserProxy.Parse(Boolean saveInternalSubset)
at System.Xml.XmlTextReaderImpl.ParseDoctypeDecl()
at System.Xml.XmlTextReaderImpl.ParseDocumentContent()
at System.Xml.XmlTextReaderImpl.Read()
at System.Xml.XmlLoader.LoadDocSequence(XmlDocument parentDoc)
at System.Xml.XmlLoader.Load(XmlDocument doc, XmlReader reader, Boolean preserveWhitespace)
at System.Xml.XmlDocument.Load(XmlReader reader)
at System.Xml.XmlDocument.LoadXml(String xml)
at ConsoleApplication36.Program.Main(String[] args) in c:\Projects\temp\ConsoleApplication36\Program.cs:line 11

12386
2017-12-14 23:30


起源

对于XEE来说也很重要 owasp.org/index.php/XML_External_Entity_(XXE)_Processing - Mark Nadig


答案:


好吧,在.NET 4.0中,XmlTextReader有一个名为DtdProcessing的属性。当设置为DtdProcessing.Ignore时,它应该禁用DTD处理。


10
2017-12-16 15:04



.net 3.5怎么样? - THX-1138
您应该尝试将XmlReader.Settings.ValidationType设置为ValidationType.None。或者,我认为将XmlReader.Settings.XmlResolver设置为null也可以做到这一点 - L.E.O
确认 doc.XmlResolver = null; 解决了这个问题。 - THX-1138


在.net 4.5.1中我没有运气将doc.XmlResolver设置为null。

对我来说最简单的解决方法是在调用LoadXml()之前使用字符串替换来将“xmlns =”更改为“ignore =”,例如,

var responseText = await response.Content.ReadAsStringAsync();
responseText = responseText.Replace("xmlns=", "ignore=");
try
{
    var doc = new XmlDocument();
    doc.LoadXml(responseText);
    ...
}

0
2017-07-06 17:42