未经许可,不得转载。
文章目录

XXE
XXE(XML External Entity,XML外部实体注入) 是一种安全漏洞,攻击者通过利用XML解析器处理外部实体的功能,读取本地文件、发起网络请求或导致拒绝服务攻击。
XXE的常见攻击场景:
1、读取本地文件:通过加载外部实体,读取服务器上的敏感文件(如/etc/passwd)。
2、发起SSRF攻击:通过外部实体发起网络请求,访问内网服务或云服务元数据。
3、拒绝服务攻击:通过构造恶意的XML实体,消耗服务器资源(如“Billion Laughs”攻击)。
常见的XML解析器
在 Java 语言中,XML 解析主要依赖以下几种方式:
1、DOM(Document Object Model)解析是一种基于树结构的解析方式,它会将整个 XML 文档加载到内存中,并构建成层次化的树形结构。这种方式适用于需要频繁读取和修改 XML 数据的场景,但由于其内存占用较大,不适合解析超大 XML 文件。
2、SAX(Simple API for XML)解析是一种基于事件驱动的解析方式,它逐行读取 XML 文档,并在解析过程中触发相应的事件进行处理。相比 DOM,SAX 解析更加轻量级,不会将整个 XML 加载到内存中,因此适用于大规模 XML 解析任务。但由于 SAX 解析是顺序读取的,不支持随意访问 XML 结构,因此修改操作较为复杂。
3、JDOM 解析是专为 Java 设计的 XML 解析库,提供了一种更简洁且面向对象的方式来操作 XML 文档。JDOM 结合了 DOM 和 SAX 的优点,既可以在内存中构建 XML 结构,也可以基于流式处理,适用于中等规模的 XML 解析任务。
4、DOM4J 解析是 JDOM 的增强版,功能更丰富,性能更优,广泛用于 Java 开发中的 XML 解析和操作。它不仅支持标准 XML 解析,还支持 XPath、XSLT 及多种 XML 处理方式,适用于复杂的 XML 解析需求。
5、Digester 解析是 Apache 开源社区提供的 XML 解析工具,基于 SAX 解析方式封装,能够将 XML 解析并转换为 Java 对象,特别适用于解析配置文件和数据映射等场景。
其中,DOM 和 SAX 是 Java 原生支持的 XML 解析方式,而 JDOM、DOM4J 和 Digester 需要额外引入第三方依赖库。在选择解析方式时,需要根据 XML 文件大小、解析性能、可读性和操作需求等因素进行权衡。
漏洞成因
XXE通常发生在应用程序解析用户提供的XML输入时,未禁用外部实体解析的情况下。
解析XML的Java方法
Java中解析XML的方法有多种,常见的有以下四种:DOM、DOM4J、JDOM 和 SAX。每种方法各有特点,适用于不同的场景。
DocumentBuilder(原生,可回显)
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.w3c.dom.Document;
import java.io.StringReader;
import org.xml.sax.InputSource;
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
StringReader sr = new StringReader(xml_con); // xml_con为XML字符串
InputSource is = new InputSource(sr);
Document document = db.parse(is); // 解析XML并返回Document对象
特点:
- 基于DOM模型,将整个XML文档加载到内存中,生成一棵DOM树。
- 可回显:解析后的内容可以通过Document对象进行操作和访问。
- 适用于需要频繁访问和修改XML内容的场景。
风险:如果未禁用外部实体解析,可能导致XXE漏洞。
SAXReader(DOM4J,第三方库)
import org.dom4j.io.SAXReader;
import org.dom4j.Document;
import javax.servlet.http.HttpServletRequest;
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(request.getInputStream()); // 从请求流中读取并解析XML
特点:
- 基于DOM4J库,提供更简洁的API。
- 可回显:解析后的内容可以通过Document对象进行操作和访问。
- 适用于需要灵活处理XML的场景。
风险:默认情况下支持外部实体解析,需显式禁用以防止XXE漏洞。
SAXBuilder(JDOM,第三方库)
import org.jdom2.input.SAXBuilder;
import org.jdom2.Document;
import javax.servlet.http.HttpServletRequest;
SAXBuilder builder = new SAXBuilder();
Document document = builder.build(request.getInputStream()); // 从请求流中读取并解析XML
特点:
- 基于JDOM库,提供更直观的API。
- 可回显:解析后的内容可以通过Document对象进行操作和访问。
- 适用于需要快速解析和操作XML的场景。
风险:默认情况下支持外部实体解析,需显式禁用以防止XXE漏洞。
SAXParserFactory(原生,不可回显)
import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.SAXParser;
import org.xml.sax.helpers.DefaultHandler;
import javax.servlet.http.HttpServletRequest;
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
DefaultHandler handler = new DefaultHandler(); // 自定义处理器
saxParser.parse(request.getInputStream(), handler); // 解析XML并触发处理器事件
特点:
- 基于SAX模型,采用事件驱动的方式解析XML。
- 不可回显:解析过程中通过事件回调处理数据,不生成完整的DOM树。
- 适用于处理大型XML文件或流式数据。
风险:默认情况下支持外部实体解析,需显式禁用以防止XXE漏洞。
其他解析方法如下。
XMLReaderFactory
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;
import org.xml.sax.InputSource;
import java.io.StringReader;
XMLReader xmlReader = XMLReaderFactory.createXMLReader();
xmlReader.parse(new InputSource(new StringReader(xml_con))); // 解析XML字符串
特点:
-
基于SAX模型,提供更底层的API。
-
不可回显:通过事件回调处理数据。
-
适用于需要自定义解析逻辑的场景。
Digester(Apache Commons Digester)
import org.apache.commons.digester3.Digester;
import java.io.StringReader;
Digester digester = new Digester();
digester.parse(new StringReader(xml_con)); // 解析XML字符串
特点:
-
基于规则驱动的解析方式,适合将XML映射为Java对象。
-
不可回显:解析过程中直接生成Java对象。
-
适用于配置文件解析或数据绑定场景。
支持XInclude的DocumentBuilder
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.w3c.dom.Document;
import java.io.StringReader;
import org.xml.sax.InputSource;
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setXIncludeAware(true); // 支持XInclude
dbf.setNamespaceAware(true); // 支持命名空间
DocumentBuilder db = dbf.newDocumentBuilder();
StringReader sr = new StringReader(xml_con);
InputSource is = new InputSource(sr);
Document document = db.parse(is); // 解析XML
特点:
-
支持XInclude和命名空间,适合处理复杂的XML文档。
-
可回显:解析后的内容可以通过Document对象进行操作和访问。
-
适用于需要高级XML特性的场景。
SAXParserFactory与XMLReader结合
import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.SAXParser;
import org.xml.sax.XMLReader;
import org.xml.sax.InputSource;
import java.io.StringReader;
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser saxParser = spf.newSAXParser();
XMLReader xmlReader = saxParser.getXMLReader();
xmlReader.parse(new InputSource(new StringReader(xml_con))); // 解析XML字符串
特点:
- 结合SAXParserFactory和XMLReader,提供更灵活的解析方式。
- 不可回显:通过事件回调处理数据。
- 适用于需要自定义解析逻辑的场景。
漏洞代码
以下漏洞代码未禁用外部实体解析:
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import java.io.ByteArrayInputStream;
import javax.servlet.http.HttpServletRequest;
public class VulnerableXXE {
public static void main(String[] args) {
HttpServletRequest request = getRequest();
// 从 GET 请求中获取 XML 内容
String xml = request.getParameter("xml");
if (xml == null || xml.isEmpty()) {
System.out.println("请提供 XML 内容作为参数");
return;
}
try {
// 创建 DocumentBuilderFactory 对象
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// 未禁用对外部实体的支持,导致 XXE 漏洞
DocumentBuilder builder = factory.newDocumentBuilder();
// 解析用户传递的 XML 内容
Document document = builder.parse(new ByteArrayInputStream(xml.getBytes()));
// 输出解析结果
System.out.println("解析结果:");
System.out.println(document.getDocumentElement().getTextContent());
} catch (Exception e) {
System.err.println("解析 XML 时发生错误:");
e.printStackTrace();
}
}
}
以上未禁用外部实体解析,攻击者可以通过<!ENTITY>标签加载外部文件(如file:///etc/passwd)。
<!ENTITY> 是 XML 中的一个声明,用于定义 实体。在 XML 中,实体可以用于以下目的:引用字符或者字符串;引用外部资源,例如文件或 URL;扩展某些 XML 元素或属性的内容。
payload:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]>
<foo>&xxe;</foo>
防范
禁用外部实体解析、对用户提供的XML输入进行严格的验证、选择默认禁用外部实体解析的库,或在初始化时显式禁用。
例如在使用DocumentBuilderFactory、SAXParserFactory等原生方法时,显式禁用外部实体解析:
factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
审计思路
全局搜索以下关键词:
javax.xml.parsers.DocumentBuilder
javax.xml.parsers.SAXParser
javax.xml.transform.TransformerFactory
javax.xml.validation.Validator
javax.xml.validation.SchemaFactory
javax.xml.transform.sax.SAXTransformerFactory
javax.xml.transform.sax.SAXSource
org.xml.sax.XMLReader
org.xml.sax.helpers.XMLReaderFactory
org.dom4j.io.SAXReader
org.jdom.input.SAXBuilder
org.jdom2.input.SAXBuilder
javax.xml.bind.Unmarshaller
javax.xml.xpath.XpathExpression
javax.xml.stream.XMLStreamReader
org.apache.commons.digester3.Digester
12万+

被折叠的 条评论
为什么被折叠?



