XXE簡介
XXE(XML外部實體注入,XML External Entity) ,漏洞在對不安全的外部實體數據進行處理時,可能存在惡意行為導致讀取任意文件、探測內網端口、攻擊內網網站、發起DoS拒絕服務攻擊、執行系統命令等問題。簡單來說,如果系統能夠接收並解析用戶的XML,但未禁用DTD和Entity時,可能出現XXE漏洞,常見場景如pdf在線解析、word在線解析、定制協議或者其他可以解析xml的API接口。
xml解析器
java解析xml有許多方法,常見有四種,即:DOM、DOM4J、JDOM 和SAX。
DocumentBuilderFactory
public class DocumentXXE {
public static void main(String[] args) throws Exception {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
String str = "<!DOCTYPE doc [ \n" +
"<!ENTITY xxe SYSTEM \"http://127.0.0.1:8888\">\n" +
"]><doc>&xxe;</doc>";
InputStream is = new ByteArrayInputStream(str.getBytes());
Document doc = db.parse(is);
}
}
其中四行代碼是xml解析的重點和標配
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
InputStream is = new ByteArrayInputStream(str.getBytes());
Document doc = db.parse(is);
網上有修復方法是這樣的:
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setExpandEntityReferences(false);
實際上這種方法是沒用的,我們都知道修復xxe的方式是禁用外部實體,owasp就推薦了三個屬性的設置:
FEATURE = "http://xml.org/sax/features/external-parameter-entities";
FEATURE = "http://xml.org/sax/features/external-general-entities";
FEATURE = "http://apache.org/xml/features/nonvalidating/load-external-dtd";
spring-data-XMLBean XXE的修復也包括了這種配置方法:
https://github.com/SvenEwald/xmlbeam/commit/f8e943f44961c14cf1316deb56280f7878702ee1
SAXBuilder
public class SAXBuilderXxe {
public static void main(String[] args) throws Exception {
String str = "<!DOCTYPE doc [ \n" +
"<!ENTITY xxe SYSTEM \"http://127.0.0.1:8888\">\n" +
"]><doc>&xxe;</doc>";
InputStream is = new ByteArrayInputStream(str.getBytes());
SAXBuilder sb = new SAXBuilder();
Document doc = sb.build(is);
}
}
修復和DocumentBuilderFactory一致。
SAXParserFactory
public class SAXParseFactoryXxe {
public static void main(String[] args) throws Exception {
String str = "<!DOCTYPE doc [ \n" +
"<!ENTITY xxe SYSTEM \"http://127.0.0.1:8888\">\n" +
"]><doc>&xxe;</doc>";
InputStream is = new ByteArrayInputStream(str.getBytes());
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser parser = spf.newSAXParser();
parser.parse(is, (HandlerBase) null);
}
}
修復和DocumentBuilderFactory一致。
SAXTransformerFactory
public class SAXTransformerFactoryXxe {
public static void main(String[] args) throws Exception {
String str = "<!DOCTYPE doc [ \n" +
"<!ENTITY xxe SYSTEM \"http://127.0.0.1:8888\">\n" +
"]><doc>&xxe;</doc>";
InputStream is = new ByteArrayInputStream(str.getBytes());
SAXTransformerFactory sf = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
StreamSource source = new StreamSource(is);
sf.newTransformerHandler(source);
}
}
修復:SAXTransformerFactory sf = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
sf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
sf.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
StreamSource source = new StreamSource(is);
sf.newTransformerHandler(source);
還有SAXReader、XMLReader、SchemaFactory、XMLInputFactory、TransformerFactory、Validator等方式,修復方式大同小異,不多說了。
總結起來就是兩種修復方式,通過設置feature的方式來防御。
一種是:
"http://apache.org/xml/features/disallow-doctype-decl", true
"http://apache.org/xml/features/nonvalidating/load-external-dtd", false
"http://xml.org/sax/features/external-general-entities", false
"http://xml.org/sax/features/external-parameter-entities", false
另一種是:
XMLConstants.ACCESS_EXTERNAL_DTD, ""
XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""
CVE-2018-8026
在solr6.6.4-7.3.1版本中,存在兩個xxe漏洞,就是因為沒有對其進行防御而造成漏洞的產生。
lucene-solr/blob/master/solr/core/src/java/org/apache/solr/schema/FileExchangeRateProvider.java

lucene-solr/blob/master/solr/core/src/java/org/apache/solr/schema/AbstractEnumField.java
顯而易見,沒有進行任何的防御。而在新版本中改用了SafeXMLParsing來進行xml解析。