摘要:它受眾廣,同時(shí)常用的解析器,例如,允許對(duì)進(jìn)行一些默認(rèn)處理。外部實(shí)體注入攻擊面對(duì)外部實(shí)體攻擊的脆弱點(diǎn)在于,解析器的庫(kù)往往都支持自定義的實(shí)體引用。
注入攻擊 XML注入
雖然JSON的出現(xiàn)實(shí)現(xiàn)了服務(wù)器與客戶端之間的“輕量級(jí)”數(shù)據(jù)交流,但是,作為另一種流行的可行方案,許多web服務(wù)API同時(shí)還是繼續(xù)支持XML。另外,除了web服務(wù)之外,XML也是許多使用XML schemas 實(shí)行數(shù)據(jù)交換的協(xié)議的基礎(chǔ),例如RSS,Atom,SOAP,以及RDF等等,舉不勝舉。
XML無(wú)處不在:它存在于web應(yīng)用的服務(wù)器中,或者在瀏覽器中作為XMLHttpRequest的請(qǐng)求和應(yīng)答的格式,亦或在瀏覽器的擴(kuò)展程序中。由于應(yīng)用廣泛,XML成為了吸引注入攻擊的目標(biāo)。它受眾廣,同時(shí)常用的XML解析器,例如libxml2,允許對(duì)XML進(jìn)行一些默認(rèn)處理。libxml2常在DOM、SimpleXML和XMLReader擴(kuò)展中的PHP中使用。當(dāng)瀏覽器的XML交換很頻繁時(shí),我們要考慮到,XML作為請(qǐng)求格式時(shí),就算是認(rèn)證用戶,也有可能正通過(guò)跨站腳本攻擊發(fā)送攻擊者所編寫(xiě)的XML。
XML外部實(shí)體注入攻擊面對(duì)XML外部實(shí)體攻擊(XXE)的脆弱點(diǎn)在于,XML解析器的庫(kù)往往都支持自定義的XML實(shí)體引用。你應(yīng)該熟悉,XML擁有表示>、<和&apos 等特殊標(biāo)記字符的實(shí)體,作為對(duì)一般實(shí)體的標(biāo)準(zhǔn)補(bǔ)充。同時(shí)XML允許用戶在XML文檔內(nèi)自定義實(shí)體,以此來(lái)擴(kuò)展其標(biāo)準(zhǔn)實(shí)體集。這些自定義實(shí)體可以直接寫(xiě)在可選的DOCTYPE中,而它們代表的擴(kuò)展值則可引用一個(gè)外部資源。正是普通XML的這種支持自定義引用、可引用外部資源內(nèi)容的可擴(kuò)展性,導(dǎo)致系統(tǒng)易受XXE的攻擊。通常,我們的系統(tǒng)絕不應(yīng)當(dāng)允許不受信任的輸入以無(wú)法預(yù)期的方式參與到系統(tǒng)交互中來(lái),同時(shí)絕大大多數(shù)程序開(kāi)發(fā)人員都不會(huì)考慮到XXE。因此值得我們特別注意。
例如,讓我們來(lái)試著定義一個(gè)新的自定義實(shí)體“harmless”。
]>
現(xiàn)在,包含這個(gè)實(shí)體定義的XML文檔可以在任何允許的地方引用&harmless;實(shí)體。
]>This result is &harmless;
XML解析器,例如PHP DOM,在解析這段XML時(shí),會(huì)在加載完文檔后立即處理這個(gè)自定義實(shí)體。因此,請(qǐng)求相關(guān)文本時(shí),會(huì)得到如下的返回:
This result is completely harmless
無(wú)疑,好處是,自定義實(shí)體可以用較短的實(shí)體名來(lái)代表重復(fù)的文本和XML。當(dāng)XML需要遵守特定的語(yǔ)法規(guī)范,或者需要自定義實(shí)體使編輯更為簡(jiǎn)單時(shí),這種方法并不少見(jiàn)。但是,考慮到遵守不信任外部輸入的原則,我們要特別小心地對(duì)待應(yīng)用程序中使用的所有XML,辨別它們的真正目的。下面的這個(gè)就肯定不是無(wú)害的輸入:
]>&harmless;
取決于請(qǐng)求的本地文件的內(nèi)容,某些內(nèi)容可用于擴(kuò)充&harmless;實(shí)體,這些內(nèi)容可以從XML解析器中提取出來(lái),包含在web應(yīng)用的輸出中,攻擊者看到它們,即會(huì)造成信息泄露。獲取的文件將會(huì)被解析成XML,除非避開(kāi)某些可以觸發(fā)解析的特殊字符,而這限制了泄露的范圍。如果文件被解析為XML但并不包含有效的XML內(nèi)容,系統(tǒng)會(huì)報(bào)錯(cuò),這樣一來(lái)可以避免內(nèi)容泄露。但是,PHP中有一個(gè)巧妙的“技倆”,可以繞過(guò)這種范圍的限制,既使得攻擊者接收不到應(yīng)答,遠(yuǎn)程HTTP請(qǐng)求卻仍然可以影響web應(yīng)用。
PHP有三種常用的方法,用來(lái)解析和使用XML:PHP DOM、SimpleXML,以及XMLReader。這三種方法都需要使用libxml2擴(kuò)展,也默認(rèn)啟用外部實(shí)體支持。這種默認(rèn)設(shè)置導(dǎo)致PHP在XXE面前很脆弱,而我們?cè)诳紤]web應(yīng)用或XML應(yīng)用庫(kù)的安全性時(shí),很容易疏忽這一點(diǎn)。
你也知道,XHTML和HTML5都可以被序列化為有效的XML,也就是說(shuō),某些XHTML頁(yè)面和被序列化的HTML5可以被解析為XML,例如,使用DOMDocument::loadXML(),而不是DOMDocument::loadHTML()時(shí)。這種XML解析方法在XEE注入的面前也很脆弱。注意,與XHTML DOCTYPES不同,libxml2目前甚至無(wú)法識(shí)別HTML5 DOCTYPE,因此無(wú)法讓其成為有效的XML。
XXE注入實(shí)例在早前的一個(gè)信息泄露的例子中,我們注意到自定義實(shí)體可能引用一個(gè)外部文件。
]>&harmless;
這會(huì)把文件內(nèi)容擴(kuò)展到自定義的&harmless;實(shí)體中。由于所有類(lèi)似的請(qǐng)求都是在本地完成的,這使得該應(yīng)用有權(quán)限讀取的所有文件內(nèi)容都可能被泄露。只要應(yīng)用的輸出中包含了這個(gè)擴(kuò)展了的實(shí)體,攻擊者就可以查看那些文件,包括沒(méi)有公開(kāi)的文件。因這種方式而造成內(nèi)容泄露的文件是相當(dāng)有限的,只能是XML文件,和不會(huì)造成XML解析錯(cuò)誤的文件。但是,PHP可以完全忽略這種限制。
]>&harmless;
PHP允許通過(guò)URI訪問(wèn)PHP wrapper,這是一般文件系統(tǒng)函數(shù),如file_get_contents()、require()、require_once()、file()、和copy()等,接受的協(xié)議之一。PHP wrapper支持一些過(guò)濾器,這些過(guò)濾器運(yùn)行在給定的資源上,結(jié)果可以通過(guò)函數(shù)調(diào)用返回。在上述例子中,我們對(duì)想要讀取的目標(biāo)文件使用了convert.base-64-encode過(guò)濾器。
這意味著,攻擊者通過(guò)利用XXE的脆弱性,可以用PHP讀取任何可讀的文件,不論文本格式如何。攻擊者只需用base64將應(yīng)用輸出解碼,就可以毫無(wú)顧忌的分析一大堆非公開(kāi)文件的內(nèi)容。盡管這本身不會(huì)直接傷害終端用戶或是應(yīng)用后臺(tái),但是它能讓攻擊者了解目標(biāo)應(yīng)用,從而以最小的代價(jià)、最低的風(fēng)險(xiǎn)發(fā)現(xiàn)應(yīng)用的其他弱點(diǎn)。
訪問(wèn)控制可以通過(guò)各種方法來(lái)實(shí)現(xiàn)。由于XXE攻擊是掛在web應(yīng)用后臺(tái)的,它無(wú)法使用當(dāng)前用戶會(huì)話產(chǎn)生任何影響,但是攻擊者仍然可以借助從本地服務(wù)器發(fā)送請(qǐng)求,來(lái)繞過(guò)后臺(tái)訪問(wèn)控制。我們來(lái)看一下下面這個(gè)簡(jiǎn)單的訪問(wèn)控制:
if (isset($_SERVER["HTTP_CLIENT_IP"]) || isset($_SERVER["HTTP_X_FORWARDED_FOR"]) || !in_array(@$_SERVER["REMOTE_ADDR"], array( "127.0.0.1", "::1", )) ) { header("HTTP/1.0 403 Forbidden"); exit( "You are not allowed to access this file." ); }
這段PHP和無(wú)數(shù)的類(lèi)似代碼都用于限制特定PHP文件對(duì)本地服務(wù)器的訪問(wèn),如 localhost。但是,應(yīng)用前端的XXE脆弱性,正好為攻擊者提供了繞過(guò)訪問(wèn)控制所需的憑證,因?yàn)閄ML解析器發(fā)出的所有HTTP請(qǐng)求都來(lái)自localhost。
]>&harmless;
如果只有本地請(qǐng)求可以查看日志,攻擊者就可以成功獲取日志。同樣的思路也適用于只接受本地請(qǐng)求的維護(hù)和管理接口。
幾乎所有可以控制服務(wù)器資源利用的東西,都可用于制造DOS攻擊。通過(guò)XML外部實(shí)體注入,攻擊者可以發(fā)送任意的HTTP請(qǐng)求,從而在恰當(dāng)?shù)臅r(shí)候耗盡服務(wù)器資源。
下文中還有一些其他的例子,通過(guò)XML實(shí)體擴(kuò)展造成XXE攻擊,從而制造潛在的DOS攻擊。
抵御XML外部實(shí)體注入這類(lèi)攻擊十分“誘人“,但對(duì)它的防御也簡(jiǎn)單的出奇。既然DOM、SimpleXML和XMLReader依賴于libxml2,我們可以簡(jiǎn)單地利用libxml_disable_entity_loader()函數(shù)來(lái)禁止外部實(shí)體引用。與此同時(shí),DOCTYPE中預(yù)定義的自定義實(shí)體卻不會(huì)受到影響,因?yàn)樗鼈儾](méi)有使用任何需要文件系統(tǒng)操作或發(fā)送HTTP請(qǐng)求的外部資源。
$oldValue = libxml_disable_entity_loader(true); $dom = new DOMDocument(); $dom->loadXML($xml); libxml_disable_entity_loader($oldValue);
在所有涉及通過(guò)字符串、文件或者遠(yuǎn)程URI來(lái)加載XML時(shí),都需要使用這些操作。
當(dāng)應(yīng)用程序及其大部分請(qǐng)求都不需要外部實(shí)體時(shí),你可以簡(jiǎn)單地從全局禁掉外部資源加載。大多數(shù)時(shí)候,這比找出所有的XML加載實(shí)例來(lái)逐個(gè)操作要更好。記住,許多庫(kù)天生自帶XEE脆弱性:
libxml_disable_entity_loader(true);
每次需要臨時(shí)允許加載外部資源時(shí),加載完后切記再把這里設(shè)為T(mén)RUE。例如,在將Docbook XML轉(zhuǎn)換為HTML時(shí),所使用的XSL樣式就是依賴于外部實(shí)體的,這里需要外部實(shí)體,但是是無(wú)害的。
但是,libxml2函數(shù)絕不是"萬(wàn)能鑰匙"。我們需要確認(rèn),其他用于解析或處理XML的擴(kuò)展和PHP庫(kù)的引用外部實(shí)體的功能,都處于關(guān)掉狀態(tài)。
如果不能通過(guò)上述方法來(lái)開(kāi)關(guān)外部實(shí)體引用,你還可以檢查一下XML文檔是否聲明了DOCTYPE。如果聲明了,同時(shí)禁掉了外部實(shí)體,則可以簡(jiǎn)單地丟棄XML文檔,拒絕可能造成解析器脆弱性的不受信任的XML訪問(wèn),同時(shí)將這種行為記錄為一次可能的攻擊。我們需要將這種行為記錄下來(lái),因?yàn)槌酥獠粫?huì)有任何系統(tǒng)報(bào)錯(cuò)記錄。可以在日常輸入驗(yàn)證中進(jìn)行這項(xiàng)檢查。但是,這種方法并不理想,筆者還是強(qiáng)烈建議從源頭上解決外部實(shí)體的問(wèn)題。
/**
Attempt a quickie detection
*/
$collapsedXML = preg_replace("/[:space:]/", "", $xml);
if(preg_match("/
throw new InvalidArgumentException( "Invalid XML: Detected use of illegal DOCTYPE" );
}
同時(shí),值得注意的是,當(dāng)我們懷疑一段數(shù)據(jù)有可能是某個(gè)攻擊的結(jié)果時(shí),最好的方法是丟棄它,而不是繼續(xù)使用它。既然它已經(jīng)表現(xiàn)出了危險(xiǎn),為什么還要繼續(xù)使用它呢?因此,將上述兩個(gè)步驟合并起來(lái),我們可以在無(wú)法丟棄數(shù)據(jù)時(shí)(例如第三方的庫(kù)),通過(guò)主動(dòng)跳過(guò)壞數(shù)據(jù)起到保護(hù)作用。之所以我們更愿意完全丟棄這些數(shù)據(jù),還因?yàn)樯衔奶岬竭^(guò)的一個(gè)理由:libxml_disable_entity_loader()不會(huì)將自定義實(shí)體完全禁掉,只有引用外部資源的才會(huì)被禁掉。因此這仍有可能導(dǎo)致一個(gè)被稱(chēng)為XML實(shí)體擴(kuò)展的注入攻擊。在下文中我們會(huì)提到這種攻擊。
原文地址:[Injection Attacks](http://phpsecurity.readthedocs.org/en/latest/Injection-Attacks.html#examples-of-xml-external-entity-injection
)
本文系 OneAPM 工程師編譯整理。OneAPM 是應(yīng)用性能管理領(lǐng)域的新興領(lǐng)軍企業(yè),能幫助企業(yè)用戶和開(kāi)發(fā)者輕松實(shí)現(xiàn):緩慢的程序代碼和 SQL 語(yǔ)句的實(shí)時(shí)抓取。想閱讀更多技術(shù)文章,請(qǐng)?jiān)L問(wèn) OneAPM 官方博客。
本文轉(zhuǎn)自 OneAPM 官方博客
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/110339.html
摘要:依賴注入和控制反轉(zhuǎn),這兩個(gè)詞經(jīng)常一起出現(xiàn)。一句話表述他們之間的關(guān)系依賴注入是控制反轉(zhuǎn)的一種實(shí)現(xiàn)方式。而兩者有大量的代碼都是可以共享的,這就是依賴注入的使用場(chǎng)景了。下一步就是創(chuàng)建具體的依賴內(nèi)容,然后注入到需要的地方這里的等于這個(gè)對(duì)象。 前言 React 是一個(gè)十分龐大的庫(kù),由于要同時(shí)考慮 ReactDom 和 ReactNative ,還有服務(wù)器渲染等,導(dǎo)致其代碼抽象化程度很高,嵌套層級(jí)...
摘要:依賴注入并不限于構(gòu)造函數(shù)作為經(jīng)驗(yàn),注入最適合必須的依賴關(guān)系,比如示例中的情況注入最適合可選依賴關(guān)系,比如緩存一個(gè)對(duì)象實(shí)例。 本文翻譯自 Symfony 作者 Fabien Potencier 的 《Dependency Injection in general and the implementation of a Dependency Injection Container in P...
摘要:故障注入為您的微服務(wù)注入故障以驗(yàn)證集群性能由于導(dǎo)師和實(shí)驗(yàn)室?guī)熜謧兊目蒲行枰救藢?zhuān)門(mén)以的模式設(shè)計(jì)了一個(gè)用于錯(cuò)誤注入的微服務(wù)模塊。 故障注入 Sidecar——為您的微服務(wù)注入故障以驗(yàn)證集群性能! 由于導(dǎo)師和實(shí)驗(yàn)室?guī)熜謧兊目蒲行枰救藢?zhuān)門(mén)以 Sidecar的模式設(shè)計(jì)了一個(gè)用于錯(cuò)誤注入的微服務(wù)模塊。該模塊可以與任何微服務(wù)應(yīng)用共同部署運(yùn)行,為其模擬cpu、內(nèi)存等錯(cuò)誤。 本項(xiàng)目的 Githu...
摘要:故障注入為您的微服務(wù)注入故障以驗(yàn)證集群性能由于導(dǎo)師和實(shí)驗(yàn)室?guī)熜謧兊目蒲行枰救藢?zhuān)門(mén)以的模式設(shè)計(jì)了一個(gè)用于錯(cuò)誤注入的微服務(wù)模塊。 故障注入 Sidecar——為您的微服務(wù)注入故障以驗(yàn)證集群性能! 由于導(dǎo)師和實(shí)驗(yàn)室?guī)熜謧兊目蒲行枰救藢?zhuān)門(mén)以 Sidecar的模式設(shè)計(jì)了一個(gè)用于錯(cuò)誤注入的微服務(wù)模塊。該模塊可以與任何微服務(wù)應(yīng)用共同部署運(yùn)行,為其模擬cpu、內(nèi)存等錯(cuò)誤。 本項(xiàng)目的 Githu...
摘要:代碼這就是控制反轉(zhuǎn)模式。是變量有默認(rèn)值則設(shè)置默認(rèn)值是一個(gè)類(lèi),遞歸解析有默認(rèn)值則返回默認(rèn)值從容器中取得以上代碼的原理參考官方文檔反射,具有完整的反射,添加了對(duì)類(lèi)接口函數(shù)方法和擴(kuò)展進(jìn)行反向工程的能力。 PHP程序員如何理解依賴注入容器(dependency injection container) 背景知識(shí) 傳統(tǒng)的思路是應(yīng)用程序用到一個(gè)Foo類(lèi),就會(huì)創(chuàng)建Foo類(lèi)并調(diào)用Foo類(lèi)的方法,假如這...
閱讀 1639·2021-09-02 15:11
閱讀 1976·2019-08-30 14:04
閱讀 2563·2019-08-27 10:52
閱讀 1582·2019-08-26 11:52
閱讀 1203·2019-08-23 15:26
閱讀 2623·2019-08-23 15:09
閱讀 2606·2019-08-23 12:07
閱讀 2234·2019-08-22 18:41