如何防止XXE攻击(XmlDocument的.NET中)(How to prevent XXE at

2019-07-18 01:07发布

我们对我们的代码安全审计,他们提到,我们的代码很容易受到外部实体(XXE)攻击。 我使用下面的代码 -

string OurOutputXMLString=
"<ce><input><transaction><length>00000</length><tran_type>Login</tran_type></transaction><user><user_id>ce_userid</user_id><subscriber_name>ce_subscribername</subscriber_name><subscriber_id>ce_subscriberid</subscriber_id><group_id>ce_groupid</group_id><permissions></permissions></user><consumer><login_details><username>UnitTester9</username><password>pDhE5AsKBHw85Sqgg6qdKQ==</password><pin>tOlkiae9epM=</pin></login_details></consumer></input></ce>"

 XmlDocument xmlDoc = new XmlDocument();
 xmlDoc.LoadXml(OurOutputXMLString);

在审计报告中,他们说,它的失败,因为XML实体可以包含可以预期contronl外解决的URL。 XML实体解析器将尝试解析和检索外部引用。 如果攻击者控制的XML可以提交到这些函数之一,那么攻击者可以获得关于内部网络,本地文件系统,或其它敏感数据的访问信息。 为了避免这种情况我写了下面的代码,但它不工作。

MemoryStream stream =
    new MemoryStream(System.Text.Encoding.Default.GetBytes(OurOutputXMLString));

XmlReaderSettings settings = new XmlReaderSettings();

settings.DtdProcessing = DtdProcessing.Prohibit;
settings.MaxCharactersFromEntities = 6000;
XmlReader reader = XmlReader.Create(stream, settings);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(reader);

但我可以看到这里的读者没有任何价值,装入xmlDoc中(XmlDocument的)。 任何人都可以帮助我在哪里丢失的东西呢? 任何帮助表示赞赏!

Answer 1:

外部资源使用的是解决XmlResolver通过提供XmlDocument.XmlResolver财产。 如果你的XML文档**不应包含任何外部资源**(例如DTD或模式),只需将此属性设置为null

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.XmlResolver = null;
xmlDoc.LoadXml(OurOutputXMLString);

如果您想筛选,其中这些URL来自(例如只允许特定的域)刚刚从派生自己的类XmlUrlResolver并覆盖ResolveUri()方法。 在那里,你可以查询的网址是什么,清理动作(例如,你可以让你的本地网络内或从信任的来源只有网址)。

例如:

class CustomUrlResovler : XmlUrlResolver
{
    public override Uri ResolveUri(Uri baseUri, string relativeUri)
    {
        Uri uri = new Uri(baseUri, relativeUri);
        if (IsUnsafeHost(uri.Host))
            return null;

        return base.ResolveUri(baseUri, relativeUri);
    }

    private bool IsUnsafeHost(string host)
    {
        return false; 
    }
}

IsUnsafeHost()是检查给定主机允许或不允许的自定义功能。 见这个职位在这里SO的一些想法。 只是返回nullResolveUri()从这类攻击保存你的代码。 万一URI允许你可以简单地返回默认XmlUrlResolver.ResolveUri()的实现。

要使用它:

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.XmlResolver = new CustomUrlResolver();
xmlDoc.LoadXml(OurOutputXMLString);

有关XML外部资源是如何解决的只是更多的细节解析外部资源的MS文档。 如果你的代码是比这个例子更复杂,那么你一定要读备注部分用于XmlDocument.XmlResolver财产。



Answer 2:

因此,它更好地使用

new XmlDocument { XmlResolver = null };

有趣的是,从.NET 4.5.2和4.6,默认的解析器行为不同,不使用前期的XmlUrlResolver隐含解决任何网址或地点,因为我看到的。

//In pre 4.5.2 it is a security issue.
//In 4.5.2 it will not resolve any more the url references in dtd and such, 
//Still better to avoid the below since it will trigger security warnings.
new XmlDocument(); 


文章来源: How to prevent XXE attack ( XmlDocument in .net)