探讨XXE防御之setFeature设置
/0x01 setFeature小谈
setFeature()
当我们使用DOM document builder或者SAX parser来解析XML格式的内容时,我们可以使用setFeature()来把一个特性设置为true或者false,从而打开或者关闭这个特性。而对于XXE的防御,正是设置相关feature的开关来实现的。
OWASP推荐的XXE防御
以DocumentBuilder的XXE为例,具体代码可看《XML注入之DocumentBuilder与XXE攻击防御>,这里只看下之前示例的XXE防御的setFeature()是设置了哪些特性:
1 | factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); |
以上设置的4个特性源自OWASP的建议,参考自《XML_External_Entity_Prevention_Cheat_Sheet》,原文解释如下:
1 | // This is the PRIMARY defense. If DTDs (doctypes) are disallowed, almost all |
下面细看下以上几个特性。
几个重要的feature
disallow-doctype-decl
防御XXE的最重要的特性,将该特性设置成true后,几乎所有的XML实体攻击都会被成功防御。
http://apache.org/xml/features/disallow-doctype-decl
True: | A fatal error is thrown if the incoming document contains a DOCTYPE declaration. |
---|---|
False: | DOCTYPE declaration is allowed. |
Default: | false |
Since: | Xerces-J 2.3.0 |
我们可以以之前DocumentBuilder的Demo为例,只调用setFeature()将该特性设置为true,然后会发现,只要在XML中尝试定义DOCTYPE的都会报错,因此便不支持解析DTD了,更不用谈后续的利用:
external-general-entities
该特性指定是否包含外部生成的实体,当设置为false时,不支持解析外部实体。
如果你不能完全禁用DTD,建议开启该特性。
http://xml.org/sax/features/external-general-entities
True: | Include external general entities. |
---|---|
False: | Do not include external general entities. |
Default: | true |
Access: | (parsing) read-only; (not parsing) read-write; |
See: | http://xml.org/sax/features/external-parameter-entities |
还是之前的例子,只调用setFeature()将该特性设置为false,先尝试解析内部实体,是OK的:
再尝试解析外部实体时,虽然会发送外部请求,但是在SYSTEM解析时就会报错了:
external-parameter-entities
该特性指定是否包含外部的参数,包括外部DTD子集。当设置为false时,不支持外部参数实体及外部DTD子集。
http://xml.org/sax/features/external-parameter-entities
True: | Include external parameter entities and the external DTD subset. |
---|---|
False: | Do not include external parameter entities or the external DTD subset. |
Default: | true |
Access: | (parsing) read-only; (not parsing) read-write; |
See: | http://xml.org/sax/features/external-general-entities |
接上一小节的示例,解析外部普通实体时,是可以成功利用的,不存在报错:
但是换种形式,当解析外部参数实体时,就会报错了:
load-external-dtd
当设置为false时,禁用外部DTD。
http://apache.org/xml/features/nonvalidating/load-external-dtd
True: | Load the external DTD. |
---|---|
False: | Ignore the external DTD completely. |
Default: | true |
Note: | This feature is always on when validation is on. |
See: | http://xml.org/sax/features/validation |
See: | http://apache.org/xml/features/nonvalidating/load-dtd-grammar |
接着上一小节的示例,尝试解析外部参数实体,是ok的:
但是换成解析外部普通实体时,就报错了:
Bypass小结
配置补全或出错,如disallow-doctype-decl设置为false等,相当于没防御,看情况而定。
下面就单一的几种设置看看,具体几种的组合的Bypass自行考虑即可:
- 如果disallow-doctype-decl设置为true,无法Bypass;
- 如果external-general-entities设置为false,则只能解析内部实体而无法解析外部实体,此时能利用的只有XXE DoS攻击,但要看具体的JDK版本;
- 如果external-parameter-entities设置为false,则解析内部实体、外部普通实体而无法解析外部参数实体,此时可以进行外部普通实体的形式来攻击或者XXE DoS;
- 如果load-external-dtd设置为false,则解析内部实体、外部参数实体而无法解析外部普通实体,此时可以进行外部参数实体的形式来攻击或者XXE DoS;