C# 解析 XML 时阻止 DTD 下载

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/215854/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 18:28:17  来源:igfitidea点击:

Prevent DTD download when parsing XML

c#.netxml

提问by spender

When using XmlDocument.Load , I am finding that if the document refers to a DTD, a connection is made to the provided URI. Is there any way to prevent this from happening?

使用 XmlDocument.Load 时,我发现如果文档引用 DTD,则会与提供的 URI 建立连接。有什么办法可以防止这种情况发生吗?

采纳答案by Richard Nienaber

After some more digging, maybe you should set the XmlResolverproperty of the XmlReaderSettings object to null.

经过更多的挖掘,也许您应该将XmlReaderSettings 对象的XmlResolver属性设置为 null。

'The XmlResolver is used to locate and open an XML instance document, or to locate and open any external resources referenced by the XML instance document. This can include entities, DTD, or schemas.'

'XmlResolver 用于定位和打开 XML 实例文档,或定位和打开 XML 实例文档引用的任何外部资源。这可以包括实体、DTD 或模式。

So the code would look like this:

所以代码看起来像这样:

        XmlReaderSettings settings = new XmlReaderSettings();
        settings.XmlResolver = null;
        settings.DtdProcessing = DtdProcessing.Parse;
        XmlDocument doc = new XmlDocument();
        using (StringReader sr = new StringReader(xml))
            using (XmlReader reader = XmlReader.Create(sr, settings))
            {
                doc.Load(reader);
            }

回答by muratgu

Use an XMLReaderto load the document and set the ValidationTypeproperty of the reader settings to None.

使用XMLReader加载文档并将ValidationType阅读器设置的属性设置为None

回答by Richard Nienaber

Try something like this:

尝试这样的事情:

XmlDocument doc = new XmlDocument();
using (StringReader sr = new StringReader(xml))
  using (XmlReader reader = XmlReader.Create(sr, new XmlReaderSettings()))
  {
     doc.Load(reader);
  }

The thing to note here is that XmlReaderSettings has the ProhibitDtdproperty set to true by default.

这里要注意的是,XmlReaderSettings 的ProhibitDtd属性默认设置为 true。

回答by spender

The document being loaded HAS a DTD.

正在加载的文档具有 DTD。

With:

和:

settings.ProhibitDtd = true;

I see the following exception:

我看到以下异常:

Service cannot be started. System.Xml.XmlException: For security reasons DTD is prohibited in this XML document. To enable DTD processing set the ProhibitDtd property on XmlReaderSettings to false and pass the settings into XmlReader.Create method.

服务无法启动。System.Xml.XmlException:出于安全原因,此 XML 文档中禁止使用 DTD。要启用 DTD 处理,请将 XmlReaderSettings 上的 ProhibitDtd 属性设置为 false 并将设置传递到 XmlReader.Create 方法。

So, it looks like ProhibitDtd MUST be set to true in this instance.

因此,在这种情况下,看起来 ProhibitDtd 必须设置为 true。

It looked like ValidationType would do the trick, but with:

看起来 ValidationType 可以解决问题,但是:

settings.ValidationType = ValidationType.None;

I'm still seeing a connection to the DTD uri.

我仍然看到与 DTD uri 的连接。

回答by Gunther Schadow

This is actually a flaw in the XML specifications. The W3C is bemoaning that people all hit their servers like mad to load schemas billions of times. Unfortunately just about no standard XML library gets this right, they all hit the servers over and over again.

这实际上是 XML 规范中的一个缺陷。W3C 哀叹人们都疯狂地访问他们的服务器以加载模式数十亿次。不幸的是,几乎没有标准的 XML 库能做到这一点,它们都一遍又一遍地攻击服务器。

The problem with DTDs is particularly serious, because DTDs may include general entity declarations (for things like &-> &) which the XML file may actually rely upon. So if your parser chooses to forgo loading the DTD, and the XML makes use of general entity references, parsing may actually fail.

DTD 的问题特别严重,因为 DTD 可能包含&XML 文件实际上可能依赖的一般实体声明(对于诸如-> & 之类的东西)。因此,如果您的解析器选择放弃加载 DTD,并且 XML 使用通用实体引用,则解析实际上可能会失败。

The only solution to this problem would be a transparent caching entity resolver, which would put the downloaded files into some archive in the library search path, so that this archive would be dynamically created and almost automatically bundled with any software distributions made. But even in the Java world there is not one decent such EntityResolver floating about, certainly not built-in to anything from apache foundation.

该问题的唯一解决方案是透明缓存实体解析器,它将下载的文件放入库搜索路径中的某个存档中,以便动态创建该存档并几乎自动与任何软件分发捆绑在一起。但即使在 Java 世界中,也没有一个像样的 EntityResolver 四处飘荡,当然也不是 apache 基金会的任何内置对象。