加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

默认情况下,XML炸弹(实体注入)在.Net 4.0中处理,但不在.Net 3.5

发布时间:2020-12-16 23:36:02 所属栏目:百科 来源:网络整理
导读:以下代码 XmlDocument xdoc = new XmlDocument(); String xml = @"!DOCTYPE lolz [" + "!ENTITY lol "lol"" + "!ENTITY lol2 "lol;lol;lol;lol;lol;lol;lol;lol;lol;lol;"" + "!ENTITY lol3 "lol2;lol2;lol2;lol2;lol2;lol2;lol2;lol2;lol2;lol2;"" +
以下代码

XmlDocument xdoc = new XmlDocument();
            String xml = @"<!DOCTYPE lolz [" +
                    "<!ENTITY lol "lol">" +
                    "<!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">" +
                    "<!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">" +
                    "<!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">" +
                    "<!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">" +
                    "<!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">" +
                    "<!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">" +
                    "<!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">" +
                    "<!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">" +
                    "]>" +
                    "<lolz>&lol9;</lolz>";
            xdoc.LoadXml(xml);

.Net 4.0
此代码将抛出异常
输入文档已超出MaxCharactersFromEntities设置的限制

.Net 2.0 / 3.5
此代码不会抛出任何异常,并且将继续以XML格式增长,直到达到内存限制

有人可以解释这种差异的原因吗?

迄今为止所做的研究
我反汇编了System.Xml v2.0和v4.0,只改变了我看到的方法RegisterConsumedCharacters
v2.0定义

private void RegisterConsumedCharacters(long characters,bool inEntityReference)
{
    if (this.maxCharactersInDocument > 0L)
    {
        long num = this.charactersInDocument + characters;
        if (num < this.charactersInDocument)
        {
            this.ThrowWithoutLineInfo("XmlSerializeErrorDetails",new string[] { "MaxCharactersInDocument","" });
        }
        else
        {
            this.charactersInDocument = num;
        }
        if (this.charactersInDocument > this.maxCharactersInDocument)
        {
            this.ThrowWithoutLineInfo("XmlSerializeErrorDetails","" });
        }
    }
    if ((this.maxCharactersFromEntities > 0L) && inEntityReference)
    {
        long num2 = this.charactersFromEntities + characters;
        if (num2 < this.charactersFromEntities)
        {
            this.ThrowWithoutLineInfo("XmlSerializeErrorDetails",new string[] { "MaxCharactersFromEntities","" });
        }
        else
        {
            this.charactersFromEntities = num2;
        }
        if ((this.charactersFromEntities > this.maxCharactersFromEntities) && XmlTextReaderSection.LimitCharactersFromEntities)
        {
            this.ThrowWithoutLineInfo("XmlSerializeErrorDetails","" });
        }
    }
}

v4.0定义

private void RegisterConsumedCharacters(long characters,bool inEntityReference)
{
    if (this.maxCharactersInDocument > 0L)
    {
        long num = this.charactersInDocument + characters;
        if (num < this.charactersInDocument)
        {
            this.ThrowWithoutLineInfo("Xml_LimitExceeded","MaxCharactersInDocument");
        }
        else
        {
            this.charactersInDocument = num;
        }
        if (this.charactersInDocument > this.maxCharactersInDocument)
        {
            this.ThrowWithoutLineInfo("Xml_LimitExceeded","MaxCharactersInDocument");
        }
    }
    if ((this.maxCharactersFromEntities > 0L) && inEntityReference)
    {
        long num2 = this.charactersFromEntities + characters;
        if (num2 < this.charactersFromEntities)
        {
            this.ThrowWithoutLineInfo("Xml_LimitExceeded","MaxCharactersFromEntities");
        }
        else
        {
            this.charactersFromEntities = num2;
        }
        if (this.charactersFromEntities > this.maxCharactersFromEntities)
        {
            this.ThrowWithoutLineInfo("Xml_LimitExceeded","MaxCharactersFromEntities");
        }
    }
}

我在这里看到的唯一区别是ThrowWithoutLineInfo的参数更改以及v4.0中XmlTextReaderSection.LimitCharactersFromEntities的删除,但我无法从中获取太多内容并且在此处遇到了阻塞.

解决方法

如MSDN文档所述,XmlReaderSettings.MaxCharactersFromEntities的默认值为0,表示“无限制”.

但是文档没有指出一个令人讨厌的技巧,在.net 4中,如果你没有将XmlReaderSettings传递给你的XmlTextReader,那么限制不会设置为0而是设置为10,000,000.

相关的源代码在这里,即使有评论指出这是一个重大变化:
https://referencesource.microsoft.com/#System.Xml/System/Xml/Core/XmlTextReaderImpl.cs,385

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读