XML外部实体引用是XML标准中定义的一种机制,允许XML文档通过声明外部实体来引用外部的文件、URL等资源,正常情况下可用于复用公共的XML片段,但如果XML解析器未对外部实体的加载做限制,就会被攻击者利用发起XXE攻击,造成敏感信息泄露、内网探测等安全问题。

XML外部实体引用的基本语法
XML中通过<!ENTITY>声明来定义实体,外部实体的声明需要指定SYSTEM关键字并跟上外部资源的地址,基本语法如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [
<!ENTITY 实体名 SYSTEM "外部资源地址">
]>
<root>
&实体名;
</root>
当解析器处理上述XML时,会先加载外部资源地址对应的内容,再将&实体名;替换为加载到的内容输出。
XXE漏洞的攻击场景示例
读取本地敏感文件
攻击者可以构造如下恶意XML,让服务器解析后返回/etc/passwd文件的内容:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<foo>
&xxe;
</foo>
发起内网端口探测
如果服务器允许加载网络地址的外部实体,攻击者可以替换SYSTEM后的地址为内网IP和端口,根据返回结果判断内网服务是否存活:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "http://192.168.0.1:8080">
]>
<foo>
&xxe;
</foo>
XML外部实体引用的防御方案
防范XXE漏洞的核心是限制XML解析器对外部实体的加载,不同语言的实现方式如下:
Java语言防御
Java中常用的XML解析器如DOM、SAX、StAX都可以通过设置属性禁用外部实体,以DOM解析为例:
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.w3c.dom.Document;
public class XxeDefense {
public static void main(String[] args) throws Exception {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// 禁用外部实体
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
DocumentBuilder db = dbf.newDocumentBuilder();
// 解析XML输入流
Document doc = db.parse(输入流对象);
}
}
Python语言防御
Python的xml.etree.ElementTree模块默认不解析外部实体,若使用lxml库需要手动禁用:
from lxml import etree
def parse_xml(xml_content):
parser = etree.XMLParser(resolve_entities=False, no_network=True)
tree = etree.fromstring(xml_content, parser)
return tree
通用防御原则
- 尽量不使用XML格式传输数据,优先选择JSON等更安全的格式
- 如果必须使用XML,禁用DOCTYPE声明,从根源上阻止外部实体定义
- 对XML输入做严格的白名单校验,过滤掉<!ENTITY、SYSTEM等关键字
- 服务器部署时限制XML解析进程的文件读取和网络访问权限,降低攻击影响范围
总结
XML外部实体引用本身是XML规范的正常功能,但缺乏限制的解析行为会直接导致XXE漏洞。开发者在开发涉及XML解析的功能时,需要主动对解析器做安全配置,同时结合输入校验和权限限制,才能有效避免该类安全问题。日常安全测试中也需要将XXE漏洞作为XML相关功能的必测项,及时排查潜在风险。
XML外部_entity_引用XXE漏洞XML解析安全防御修改时间:2026-07-10 13:00:34