JAVA代码审计之XXE与SSRF
字数 995 2025-08-27 12:33:31

Java代码审计之XXE与SSRF漏洞详解

一、XXE漏洞

1. XXE漏洞简介

XXE(XML外部实体注入,XML External Entity)是应用程序在解析XML输入时,当允许引用外部实体时,攻击者可构造恶意内容导致的安全漏洞。利用XXE可以:

  • 读取任意文件
  • 探测内网端口
  • 攻击内网网站
  • 发起DoS拒绝服务攻击
  • 执行系统命令

Java中的XXE支持sun.net.www.protocol里的所有协议:http, https, file, ftp, mailto, jar, netdoc。

2. XML基础概念

XML & DTD

  • XML(可扩展标记语言):用于传输和存储数据的标记语言
  • DTD(文档类型定义):定义XML文档的合法构建模块

实体(ENTITY)类型

  1. 字符实体:类似HTML实体编码,如&a;(十进制)或&a;(十六进制)
  2. 命名实体(内部实体)
    <!ENTITY x "First Param!">
    
  3. 外部普通实体
    <!ENTITY outfile SYSTEM "outfile.xml">
    
  4. 外部参数实体
    <!ENTITY % param1 "Hello">
    

3. XXE审计函数

需要关注的XML解析接口:

javax.xml.parsers.DocumentBuilderFactory;
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

4. 常用测试POC

有回显时(利用file协议读取文件)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE lltest[
<!ENTITY xxe SYSTEM "file:///C:/Windows/win.ini">
]> 
<user><username>&xxe;</username><password>123456</password></user>

无回显时(利用http协议探测)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE note[
<!ENTITY % lltest SYSTEM "http:7777/lltest_xxe666">
%lltest;
]>

5. XXE漏洞代码示例

1) DOM解析方式

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(request.getInputStream());

2) DOM4J解析方式

SAXReader saxReader = new SAXReader();
Document document = saxReader.read(request.getInputStream());

3) JDOM2解析方式

SAXBuilder builder = new SAXBuilder();
Document document = builder.build(request.getInputStream());

4) SAX解析方式

SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxparser = factory.newSAXParser();
saxparser.parse(request.getInputStream(), handler);

6. XXE漏洞防御

以DOM - DocumentBuilderFactory为例的防御代码:

dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); //禁用DTDs

// 如果不能禁用DTDs,使用以下两项
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);

二、SSRF漏洞

1. SSRF漏洞简介

SSRF(Server-Side Request Forge, 服务端请求伪造)是攻击者让服务端发起指定请求的攻击方式,目标通常是从外网无法访问的内网系统。

Java中SSRF支持的协议:http, https, file, ftp, mailto, jar, netdoc。

2. SSRF审计函数

需要关注的发起HTTP请求的类及函数:

HttpURLConnection.getInputStream
URLConnection.getInputStream
Request.Get.execute
Request.Post.execute
URL.openStream
ImageIO.read
OkHttpClient.newCall.execute
HttpClients.execute
HttpClient.execute

3. SSRF漏洞代码示例

1) HttpURLConnection方式

String url = request.getParameter("url");
URL u = new URL(url);
URLConnection urlConnection = u.openConnection();
HttpURLConnection httpUrl = (HttpURLConnection)urlConnection;
BufferedReader in = new BufferedReader(new InputStreamReader(httpUrl.getInputStream()));

2) URLConnection方式

String url = request.getParameter("url");
URL u = new URL(url);
URLConnection urlConnection = u.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));

3) ImageIO方式

String url = request.getParameter("url");
URL u = new URL(url);
BufferedImage img = ImageIO.read(u);

4) 其他方式

// Request方式
Request.Get(url).execute().returnContent().toString();

// openStream方式
URL u = new URL(url);
inputStream = u.openStream();

// OkHttpClient方式
OkHttpClient client = new OkHttpClient();
Request ok_http = new Request.Builder().url(url).build();
client.newCall(ok_http).execute();

// HttpClients方式
CloseableHttpClient client = HttpClients.createDefault();
HttpGet httpGet = new HttpGet(url);
HttpResponse httpResponse = client.execute(httpGet);

4. SSRF漏洞防御

防御措施:

  1. 限制协议为HTTP、HTTPS协议
  2. 禁止30x跳转
  3. 设置URL白名单或者限制内网IP
  4. 限制请求的端口为http常用端口

示例防御代码:

String url = request.getParameter("url");
if (!SSRFHostCheck(url)) {
    System.out.println("warning!!! illegal url:" + url);
    return;
}

URL u = new URL(url);
URLConnection urlConnection = u.openConnection();
HttpURLConnection httpUrl = (HttpURLConnection)urlConnection;
httpUrl.setInstanceFollowRedirects(false); //禁止30x跳转

public static Boolean SSRFHostCheck(String url) {
    try {
        URL u = new URL(url);
        // 限制为http和https协议
        if (!u.getProtocol().startsWith("http") && !u.getProtocol().startsWith("https")) {
            return false;
        }
        // 获取域名或IP
        String host = u.getHost().toLowerCase();
        String hostwhitelist = "192.168.199.209"; //白名单
        return host.equals(hostwhitelist);
    } catch (Exception e) {
        return false;
    }
}

参考资源

  1. Java XXE与SSRF示例代码
  2. XXE Lab示例
  3. Java安全代码示例
Java代码审计之XXE与SSRF漏洞详解 一、XXE漏洞 1. XXE漏洞简介 XXE(XML外部实体注入,XML External Entity)是应用程序在解析XML输入时,当允许引用外部实体时,攻击者可构造恶意内容导致的安全漏洞。利用XXE可以: 读取任意文件 探测内网端口 攻击内网网站 发起DoS拒绝服务攻击 执行系统命令 Java中的XXE支持 sun.net.www.protocol 里的所有协议:http, https, file, ftp, mailto, jar, netdoc。 2. XML基础概念 XML & DTD XML(可扩展标记语言):用于传输和存储数据的标记语言 DTD(文档类型定义):定义XML文档的合法构建模块 实体(ENTITY)类型 字符实体 :类似HTML实体编码,如 &a; (十进制)或 &a; (十六进制) 命名实体(内部实体) : 外部普通实体 : 外部参数实体 : 3. XXE审计函数 需要关注的XML解析接口: 4. 常用测试POC 有回显时(利用file协议读取文件) 无回显时(利用http协议探测) 5. XXE漏洞代码示例 1) DOM解析方式 2) DOM4J解析方式 3) JDOM2解析方式 4) SAX解析方式 6. XXE漏洞防御 以DOM - DocumentBuilderFactory为例的防御代码: 二、SSRF漏洞 1. SSRF漏洞简介 SSRF(Server-Side Request Forge, 服务端请求伪造)是攻击者让服务端发起指定请求的攻击方式,目标通常是从外网无法访问的内网系统。 Java中SSRF支持的协议:http, https, file, ftp, mailto, jar, netdoc。 2. SSRF审计函数 需要关注的发起HTTP请求的类及函数: 3. SSRF漏洞代码示例 1) HttpURLConnection方式 2) URLConnection方式 3) ImageIO方式 4) 其他方式 4. SSRF漏洞防御 防御措施: 限制协议为HTTP、HTTPS协议 禁止30x跳转 设置URL白名单或者限制内网IP 限制请求的端口为http常用端口 示例防御代码: 参考资源 Java XXE与SSRF示例代码 XXE Lab示例 Java安全代码示例