阻止XmlReader扩展XML实体

时间:2017-03-13 13:43:22

标签: c# .net xml dtd xmlreader

有没有办法阻止.NET的XmlReader类在阅读内容时将XML实体扩展为其值?

例如,假设以下XML用作输入:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE author PUBLIC "ISO 8879:1986//ENTITIES Added Latin 1//EN//XML" "http://www.oasis-open.org/docbook/xmlcharent/0.3/iso-lat1.ent" >
<author>&aacute;</author>

我们假设无法达到扩展aacute实体所需的外部OASIS DTD。我希望读者按顺序阅读author元素,然后是类型EntityReference的aacute节点,最后是作者end元素,而不会抛出任何错误。我怎样才能做到这一点?

更新:我还想阻止&#x00E1;等字符实体的扩展。

2 个答案:

答案 0 :(得分:1)

一种方法是使用`XmlTextReader',如下所示:

using (var reader = new XmlTextReader(@"your url"))
{
    // note this
    reader.EntityHandling = EntityHandling.ExpandCharEntities;
    while (reader.Read())
    {
        // here it will be EntityReference with no exceptions
    }
}

如果这不是一个选项 - 你可以对XmlReader做同样的事情,但需要一些反思(至少我不知道另一种方式):

using (var reader = XmlReader.Create(@"your url", new XmlReaderSettings() {
    DtdProcessing = DtdProcessing.Ignore // or Parse
})) {
     // get internal property which has the same function as above in XmlTextReader
     reader.GetType().GetProperty("EntityHandling", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(reader, EntityHandling.ExpandCharEntities);
     while (reader.Read()) {
          // here it will be EntityReference with no exceptions
     }
 }

答案 1 :(得分:1)

XML解析很危险。在某些情况下,它允许CVE和拒绝服务攻击。

例如CVE-2016-3255

同样在Black Hat EU 2013

上讨论了这个问题

最感兴趣的文件是MLDTDEntityAttacks 它为开发人员提供了实现和Recomendations。

检索资源

<!DOCTYPE roottag [
 <!ENTITY windowsfile SYSTEM "file:///c:/boot.ini">
]>
<roottag>
 <sometag>&windowsfile;</sometag>
</roottag>

<强>的DoS

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE root
  [
  <!ENTITY a0 "test" >
  <!ENTITY a1 "&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;">
  <!ENTITY a2 "&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;">
  <!ENTITY a3 "&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;">
  <!ENTITY a4 "&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;">
  ]>
<root>&a4;</root>

回到你的问题 正如@Evk所写: 通过设置EntityHandling,您可以阻止扩展除CharEntities之外的所有实体。

除了你自己的XmlReader实现之外,我不知道防止扩展CharEntity的解决方案。

我认为您还希望阻止解析&amp; &apos; &lt; &gt; &quot;

FYI XmlTextReader解析CharEntity的方式和位置

XmlTextReader的
ParseElementContent
& case
ParseText
Char entity case
ParseCharRefInline

此函数最终解析数字字符实体引用(例如&#32;&#x00E1;
ParseNumericCharRefInline


此函数解析命名字符实体引用(&amp; &apos; &lt; &gt; &quot;
ParseNamedCharRef