XXE漏洞写法及防御

未知写,焉能防

以下内容引自先知社区「Spoock」在其「JAVA常见的XXE漏洞写法和防御」的博文,具体内容已经是精简后的版本:

前言

最近经常看到有Java项目爆出XXE的漏洞并且带有CVE,包括Spring-data-XMLBean XXE漏洞JavaMelody组件XXE漏洞解析Apache OFBiz漏洞。微信支付SDK的XXE漏洞。本质上xxe的漏洞都是因为对xml解析时允许引用外部实体,从而导致读取任意文件、探测内网端口、攻击内网网站、发起DoS拒绝服务攻击、执行系统命令等。

不同库的Java XXE漏洞

测试用payload:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [
        <!ENTITY xxe SYSTEM "dnslog-ip">
        ]>
<evil>&xxe;</evil>

DocumentBuilderFactory

错误的修复方式:

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = dbf.newDocumentBuilder();
String FEATURE = null;
FEATURE = "http://javax.xml.XMLConstants/feature/secure-processing";
dbf.setFeature(FEATURE, true);
FEATURE = "http://apache.org/xml/features/disallow-doctype-decl";
dbf.setFeature(FEATURE, true);
FEATURE = "http://xml.org/sax/features/external-parameter-entities";
dbf.setFeature(FEATURE, false);
FEATURE = "http://xml.org/sax/features/external-general-entities";
dbf.setFeature(FEATURE, false);
FEATURE = "http://apache.org/xml/features/nonvalidating/load-external-dtd";
dbf.setFeature(FEATURE, false);
dbf.setXIncludeAware(false);
dbf.setExpandEntityReferences(false);
// 读取xml文件内容
FileInputStream fis = new FileInputStream("path/to/xxexml");
InputSource is = new InputSource(fis);
builder.parse(is);

看似设置得很很全面,但是直接仍然会被攻击,原因就是在于DocumentBuilder builder = dbf.newDocumentBuilder();这行代码需要在dbf.setFeature()之后才能够生效;

正确的修复方式

SAXBuilder

这个库貌似使用得不是很多。SAXBuilder如果使用默认配置就会触发XXE漏洞;如下

修复方法

  • 方式一

  • 方式二

SAXParserFactory

同样地,在默认配置下就会存在XXE漏洞。

修复方法

SAXReader

在默认情况下会出现XXE漏洞。

修复方法

SAXTransformerFactory

在默认情况下会出现XXE漏洞

修复方法

通过跟踪源代码发现,XMLConstants.ACCESS_EXTERNAL_DTD的内容是http://javax.xml.XMLConstants/property/accessExternalDTD,XMLConstants.ACCESS_EXTERNAL_STYLESHEEThttp://javax.xml.XMLConstants/property/accessExternalStylesheet

SchemaFactory

在默认情况下也会出现XXE漏洞。

修复方法

TransformerFactory

使用默认的解析方法会存在XXE问题。

修复方法

ValidatorSample

使用默认的解析方法会存在XXE问题

修复方法

XMLReader

使用默认的解析方法会存在XXE问题

修复方法

Unmarshaller(唯一的不存在XXE的库)

使用默认的解析方法不会存在XXE问题,这也是唯一一个使用默认的解析方法不会存在XXE的一个库。

总结

其实,通过对不同的XML解析库的修复方式可以发现,XXE的防护值需要限制带外实体的注入就可以了,修复方式也简单,需要设置几个选项为false即可,可能少许的几个库可能还需要设置一些其他的配置,但是都是类似的。

总体来说修复方式都是通过设置feature的方式来防御XXE。两种方法分别是:

配置如上。

另外一种是:

本质上XXE的问题就是一个配置不当的问题,即容易发现也容易防御,但是前提是需要知道有这个漏洞,这也是就是很多开发人员因为不知道XXE最终写出了含有漏洞的代码。

最后更新于