Java如何安全地解析XML 防止XXE和DoS攻击

21次阅读

java解析xml必须禁用XXE并限制资源消耗,否则可能导致信息泄露、DoS或RCE;需通过设置features禁用DOCTYPE和外部实体,限制解析深度与大小,优先使用StAX流式解析,并叠加专用安全库与运行时防护。

Java如何安全地解析XML 防止XXE和DoS攻击

Java解析XML时,必须禁用外部实体(XXE)并限制解析器资源消耗,否则可能引发敏感信息泄露、服务拒绝(DoS)甚至远程代码执行。

禁用XXE:关闭外部实体和DTD处理

默认的JAXP解析器(如DocumentBuilder、SAXParser、XMLReader)可能启用DTD和外部实体解析,这是XXE漏洞的根源。关键操作是显式配置解析器工厂,关闭相关功能:

  • red”>DocumentBuilderFactory:调用setFeature("http://apache.org/xml/features/disallow-doctype-decl", true)禁用DOCTYPE声明;再设setFeature("http://xml.org/sax/features/external-general-entities", false)setFeature("http://xml.org/sax/features/external-parameter-entities", false)
  • SAXParserFactory:同样设置上述三个feature为false
  • TransformerFactory(用于XSLT):调用setFeature("http://javax.xml.XMLConstants/feature/secure-processing", true),并禁用扩展函数(setAttribute("http://javax.xml.transform.TransformerFactory/feature/enable-integration", false)

防御DoS:限制解析深度、大小与实体展开

攻击者可通过递归实体、超长文本或深层嵌套标签耗尽内存或CPU。需主动设限:

  • 设置ENTITY expansion limit:JDK 8u191+支持setFeature("http://apache.org/xml/features/dom/defer-node-expansion", false)配合setFeature("http://apache.org/xml/features/security/max-entity-depth", 5)等(需使用Xerces或较新JDK)
  • 限制输入长度:在解析前检查XML字节数(如inputstream.available()不准确,建议用BufferedInputStream读取头若干KB判断是否过大)
  • 避免使用DOM解析超大XML;优先选SAXStAX流式解析,它们不一次性加载全部节点到内存

推荐安全解析方式:优先使用StAX或白名单DOM

StAX(Streaming API for XML)天然不易受XXE影响,且可控性强:

立即学习Java免费学习笔记(深入)”;

  • XMLInputFactory.newFactory()获取工厂后,立即调用factory.setProperty(XMLInputFactory.SUPPORT_DTD, false)factory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false)
  • 若必须用DOM,只允许解析已知结构的XML,并配合Schema或XSD校验;解析后手动遍历检查是否存在ENTITYSYSTEM等危险关键字
  • 永远不要用javax.xml.parsers.DocumentBuilder.parse(new InputSource(new StringReader(userInput)))这类直接解析不可信字符串的方式

额外加固:使用专用安全库与运行时防护

依赖JDK默认配置风险高,建议叠加防护层:

  • 引入OWASP Java html SanitizerApache Commons Text预处理XML字符串,移除DOCTYPE、ENTITY声明
  • 在应用层设置超时与线程限制:如用ExecutorService包装解析任务,设定maxWait与timeout
  • JDK 9+启用--add-opens java.xml/com.sun.org.apache.xerces.internal.impl仅当必须调用内部类;但更推荐升级到JDK 17+,其默认开启更多安全特性
text=ZqhQzanResources