-->

DTD禁止在XML文档中的例外(DTD prohibited in xml document exc

2019-07-05 02:54发布

我越来越试图通过在C#应用程序的XML文档进行解析时,此错误:

“出于安全考虑,DTD禁止此XML文档中。要启用DTD处理上设置XmlReaderSettings为false ProhibitDtd财产并通过设置成XmlReader.Create方法。”

作为参考,该异常发生在下面的代码的第二行:

using (XmlReader reader = XmlReader.Create(uri))
{
    reader.MoveToContent(); //here

    while (reader.Read()) //(code to parse xml doc follows).

我的XML的知识是相当有限,我不知道DTD处理也不怎么办错误信息显示什么。 任何帮助,以什么可能会造成这个问题以及如何解决它? 谢谢...

Answer 1:

需要注意的是settings.ProhibitDtd现在已经过时了,用DtdProcessing代替:(新的选择忽略,解析,或禁止)

XmlReaderSettings settings = new XmlReaderSettings();
settings.DtdProcessing = DtdProcessing.Parse;

并且在这个岗位说明: 如何进行十亿笑XML DoS攻击的工作?

你应该添加一个限制的字符数,以避免DoS攻击:

XmlReaderSettings settings = new XmlReaderSettings();
settings.DtdProcessing = DtdProcessing.Parse;
settings.MaxCharactersFromEntities = 1024;


Answer 2:

首先,一些背景。

什么是DTD?

你正在试图解析该文件包含一个文档类型声明; 如果你看一下文件,你会发现附近开始的字符序列开头<!DOCTYPE和结束与相应的> 。 这样的声明允许XML处理器验证对一组指定一组的元素和属性的并约束它们可以具有什么值或内容声明的文件。

由于实体也在DTD中声明,一个DTD允许处理器知道如何扩展到实体的引用。 (实体pubdate可能被定义为包含文档的发布日期,如“2012年12月15”,并提到了几次文档作为&pubdate; -因为实际的日期只发出一次,在实体声明,这种用法可以更容易地保持于公布之日起的各种引用文档相互一致,)。

什么是一个DTD是什么意思?

文档类型声明具有纯声明的含义:此文档类型的模式,在XML规范中定义的语法,可以在某某位置找到。

与XML基础薄弱把握写的人一些软件从声明的含义的基本遭受混乱; 它假定文档类型声明的意义不声明 (架构在那边),而且是必须的 (请验证此文件)。 您正在使用的解析器似乎是这样的解析器; 它假定被交给它具有文档类型声明的XML文档,您所要求的某种处理。 它的作者可能会受益于如何从用户接受运行时参数的补救过程。 (你看它是如何努力为一些人所理解的声明语义:。一些XML解析器连创作者有时无法理解他们,陷入势在必行的思维,而不是叹气)

这些是什么“安全原因”,他们都在谈论什么?

一些安全意识的人已经决定,DTD处理(没有验证的验证,或者实体扩展),构成了安全风险。 使用实体扩张,很容易使其中的扩大,当所有的实体完全展开,成为一个非常大的文档非常小的XML数据流。 搜索在所谓的信息“十亿笑攻击”,如果你想了解更多。

以防止数十亿笑攻击一个显而易见的方法是为那些谁调用用户提供的或不可信的数据分析器调用解析器这就限制了内存或时间解析过程中被允许消费量的环境。 自1960年代中期这样的资源限制一直操作系统的标准件。 对于仍不清楚我的理由,然而,一些安全意识的人认为正确的答案是没有资源限制运行在不受信任的输入解析器,在明显的信念,这是安全的,只要你把它无法验证输入针对商定的模式。

这就是为什么你的系统是告诉你,你的数据有安全问题。

对一些人来说,想法的DTD存在安全风险听起来更像是比偏执感好,但我不相信他们是正确的。 记住(一),一个健康的偏执狂是什么样的安全专家们在生活中需要的,和(b)任何人在安全真正感兴趣的就坚持在任何情况下,资源限制 - 在对分析过程资源限制的存在,是的DTD无害。 DTD中的禁止是不是偏执狂,但拜物教。


现在,这样的背景下出的方式...

你如何解决这个问题?

最好的解决办法是悻悻抱怨你的供应商,他们已被愚弄了一个老成家的关于XML安全的故事,并告诉他们,如果他们关心安全,他们应该做一个合理的安全分析,而不是禁止的DTD。

同时,作为信息提示,你可以在“设置XmlReaderSettings为false ProhibitDtd财产并通过设置成XmlReader.Create方法。” 如果输入的是其实不可信,你也可能会考虑给予的过程中适当的资源限制的方式。

而作为备用(我不建议这样做),你可以在你输入注释文档类型声明。



Answer 3:

至于固定这一点,有一点环顾四周,我发现这是因为添加简单:

XmlReaderSettings settings = new XmlReaderSettings();
settings.ProhibitDtd = false;

并通过这些设置到创建方法。

[UPDATE 2017年3月9日]

正如一些人指出,.ProhibitDTDT现在已经过时。 亚伦Dishno医生的回答,下面,显示了替代的解决方案



文章来源: DTD prohibited in xml document exception