java代码学习(七)——xxe漏洞


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 = " "\n" +
"]>&xxe;";
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 = " "\n" +
"]>&xxe;";
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 = " "\n" +
"]>&xxe;";
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 = " "\n" +
"]>&xxe;";
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解析。

相关