赞
踩
The parser has encountered more than "64000" entity expansions in this document; this is the limit imposed by the JDK.
在运行 Java 应用程序时,出现了 XML 解析异常。具体表现为:
报错信息显示无法创建 StAX(Streaming API for XML)解析器,具体原因是超过了 JDK 默认的 64,000 个实体扩展限制。
以下是日志中的关键部分:
Exception in thread "Thread-6" com.sun.xml.internal.ws.streaming.XMLReaderException: Unable to create StAX reader or writer
at com.sun.xml.internal.ws.api.streaming.XMLStreamReaderFactory.create(XMLStreamReaderFactory.java:359)
...
Caused by: javax.xml.stream.XMLStreamException: Parser error at [row,col]:[1,1]
Message: JAXP00010004: The parser has encountered more than "64000" entity expansions in this document; this is the limit imposed by the JDK.
at com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.next(XMLStreamReaderImpl.java:219)
...
Exception in thread "Thread-6" com.sun.xml.internal.ws.streaming.XMLReaderException: Unable to create StAX reader or writer
...
Caused by: javax.xml.stream.XMLStreamException: Parser error at [row,col]:[1,1]
Message: JAXP00010004: The parser has encountered more than "64000" entity expansions in this document; this is the limit imposed by the JDK.
这个异常信息表明,由于 XML 文档中的实体扩展数量超过了 JDK 的默认限制,导致无法创建 StAX 解析器。JDK(Java 开发工具包)为了防止 XML bomb 攻击,对实体扩展设置了默认限制(64,000 个)。
在 XML 中,实体扩展(Entity Expansion)指的是对 XML 实体(Entities)的引用和替换。实体是 XML 中的一种构造,它允许在文档中定义和使用替代符号,以减少冗余或增强可读性。实体可以是字符实体、参数实体或外部实体。
字符实体:
< 表示 <
> 表示 >
& 表示 &
内部实体:
<!DOCTYPE example [
<!ENTITY example "This is an example entity.">
]>
<example>&example;</example>
&example;
是一个实体引用,在解析时会被替换为 This is an example entity.
。外部实体:
<!DOCTYPE example [
<!ENTITY example SYSTEM "http://example.com/entity.txt">
]>
<example>&example;</example>
实体扩展的机制在处理复杂和嵌套的实体引用时,可能会导致安全性问题。特别是,恶意用户可以创建大量嵌套的实体引用,导致解析器在处理时消耗大量资源,进而引发所谓的“XML bomb”攻击。例如:
<!DOCTYPE bomb [
<!ENTITY a "aaaaa... (1万次) ...aaaaa">
<!ENTITY b "&a;&a;&a;&a;&a;... (1万次) ...&a;">
<!ENTITY c "&b;&b;&b;&b;&b;... (1万次) ...&b;">
]>
<bomb>&c;</bomb>
在这种情况下,解析器必须扩展所有这些实体引用,可能会消耗大量的内存和 CPU,导致拒绝服务(DoS)。
为了防止这种类型的攻击,JDK 在 XML 解析器中设置了实体扩展的默认限制。这个限制在当前版本中是 64,000 个实体扩展。如果文档中的实体扩展超过这个数量,解析器会抛出异常。
为了解决实体扩展数量超限的问题,可以增加 JDK 的实体扩展限制:
运行时设置系统属性:
java -DentityExpansionLimit=100000 -jar your-application.jar
代码中设置系统属性:
public class Main {
public static void main(String[] args) {
System.setProperty("entityExpansionLimit", "100000");
// 启动应用程序
}
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。