1. 程式人生 > >Xml外部實體注入漏洞(XXE)與防護

Xml外部實體注入漏洞(XXE)與防護

Xml外部實體注入(XXE)

除了json外,xml也是一種常用的資料傳輸格式。對xml的解析有以下幾種常用的方式:DOM,SAX,JDOM,DOM4J,StAX等。然而這幾種解析方式都可能會出現外部實體注入漏洞,如微信支付的回撥就出現過(見參考資料2)。

XML文件結構包括xml宣告,DTD文件型別定義(可選)和文件元素,如下圖所示:
這裡寫圖片描述

DTD的作用是定義XML文件的合法構建模組,可以在XML文件內宣告,也可以外部引用。當DTD引用外部實體,而外部實體中含有惡意程式碼時,就可能會在解析xml時執行外部實體中的惡意程式碼。這就是xml外部實體注入。

舉個簡單的栗子如下圖所示:
這裡寫圖片描述

這裡通過引用外部實體,讀取了/etc/passwd。詳細的例子見參考資料1。

XXE防護

DOM解析防護(JAXP DocumentBuilderFactory, SAXParserFactory and DOM4J)

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException; // catching unsupported features
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
String FEATURE = null
; try { // 首要選擇。不允許DTDs,幾乎可以阻止所有的XML實體攻擊 FEATURE = "http://apache.org/xml/features/disallow-doctype-decl"; dbf.setFeature(FEATURE, true); } catch (ParserConfigurationException e) { // This should catch a failed setFeature feature logger.info("ParserConfigurationException was thrown. The feature '"
+ FEATURE + "' is probably not supported by your XML processor."); } catch (SAXException e) { // On Apache, this should be thrown when disallowing DOCTYPE logger.warning("A DOCTYPE was passed into the XML document"); } catch (IOException e) { // XXE that points to a file that doesn't exist logger.error("IOException occurred, XXE may still possible: " + e.getMessage()); } DocumentBuilder safebuilder = dbf.newDocumentBuilder(); 如果不能完全禁用DTDs,那麼至少使用以下方案: DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); String FEATURE = null; try { // If you can't completely disable DTDs, then at least do the following: // Xerces 1 - http://xerces.apache.org/xerces-j/features.html#external-general-entities // Xerces 2 - http://xerces.apache.org/xerces2-j/features.html#external-general-entities // JDK7+ - http://xml.org/sax/features/external-general-entities FEATURE = "http://xml.org/sax/features/external-general-entities"; dbf.setFeature(FEATURE, false); // Xerces 1 - http://xerces.apache.org/xerces-j/features.html#external-parameter-entities // Xerces 2 - http://xerces.apache.org/xerces2-j/features.html#external-parameter-entities // JDK7+ - http://xml.org/sax/features/external-parameter-entities FEATURE = "http://xml.org/sax/features/external-parameter-entities"; dbf.setFeature(FEATURE, false); // Disable external DTDs as well FEATURE = "http://apache.org/xml/features/nonvalidating/load-external-dtd"; dbf.setFeature(FEATURE, false); // 此處依據為Timothy Morgan's 2014的論文: "XML Schema, DTD, and Entity Attacks" dbf.setXIncludeAware(false); dbf.setExpandEntityReferences(false); // 以下注意點同樣出自Timothy Morgan's的論文 // If for some reason support for inline DOCTYPEs are a requirement, then // ensure the entity settings are disabled (as shown above) and beware that SSRF attacks // (http://cwe.mitre.org/data/definitions/918.html) and denial // of service attacks (such as billion laughs or decompression bombs via "jar:") are a risk." // remaining parser logic } catch (ParserConfigurationException e) { // This should catch a failed setFeature feature logger.info("ParserConfigurationException was thrown. The feature '" + FEATURE + "' is probably not supported by your XML processor."); } catch (SAXException e) { // On Apache, this should be thrown when disallowing DOCTYPE logger.warning("A DOCTYPE was passed into the XML document"); } catch (IOException e) { // XXE that points to a file that doesn't exist logger.error("IOException occurred, XXE may still possible: " + e.getMessage()); } DocumentBuilder safebuilder = dbf.newDocumentBuilder();

其他解析方式的xxe防護見官方文件(參考資料3),裡面寫得很詳細,這裡就不復制了。

參考資料: