默认情况下,XML炸弹(实体注入)在.Net 4.0中处理,但不在.Net 3.5中.怎么样?改变了什么?

use*_*954 6 .net xml security system.xml

以下代码

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);
Run Code Online (Sandbox Code Playgroud)

.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", new string[] { "MaxCharactersInDocument", "" });
        }
    }
    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", new string[] { "MaxCharactersFromEntities", "" });
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

jod*_*ods 3

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

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

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