现在百度”XXE漏洞修复”,搜索到的Java语言修复方案大部分如下:
1 |
DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance(); |
经过实际的测试发现setExpandEntityReferences(false)
根本无法防御XXE漏洞!不禁思考到两个问题:
- setExpandEntityReferences为何无法防御XXE?
- 为何一个无法防御的方案,却广为流传?
上一周我们深入Java内置XML解析器中,研究XXE漏洞的深层原理。这周我们在这个基础上,进一步弄清以上两个问题。
0x01 测试代码
1 |
import org.w3c.dom.Document; |
test.dtd
1 |
test by c0ny1 |
0x02 原理分析
我们在dbf.setExpandEntityReferences(false);
打断点开始分析!
setExpandEntityReferences(false)会将DocumentBuilderFactory对象中的expandEntityRef属性默认值true修改为false。
在newDocumentBuilder()会方法返回一个DocumentBuilderImpl对象前,会在DocumentBuilderImpl对象初始化时,调用setFeature()方法对DOM解析器的CREATE_ENTITY_REF_NODES_FEATURE
(http://apache.org/xml/features/dom/create-entity-ref-nodes) 配置项设置为上一步的expandEntityRef变量的相反值true。
domParser.setFeature()最终会调用解析器配置对象设置目标配置项的值。
在XMLParser对象调用reset()方法重置状态时,AbstractDOMParser对象中通过解析器的配置对象获取到CREATE_ENTITY_REF_NODES
(http://apache.org/xml/features/dom/create-entity-ref-nodes) 配置项的值true,并将fCreateEntityRefNodes
属性设置为true。
在XMLDocumentFragmentScannerImpl.scanDocument()进入START_ELEMENT
阶段后,next()方法会对XML中的元素进行扫描。当扫描到文本中的&
字符时(识别一般实体),解析器会调用scanEntityReference() 扫描实体引用。最后会调用setupCurrentEntity()创建连接并发起请求,以获取外部实体的内容,这时XXE漏洞将会触发!可以发现程序运行流程,依然会执行到XXE漏洞触发的位置。
继续跟踪,AbstractDOMParser.endGeneralEntity()
在判断fCreateEntityRefNodes
为false
时,实体引用&xxe将会被从DOM树删除,引用的具体内容Test by c0ny1
将会在DOM树中展开,替换掉&xxe。此时为true
,实体引用节点将保留在DOM树中。这是setExpandEntityReferences方法对XML解析器处理XML最终产生影响的位置。
最终调用链如下:
经过以上分析,我们大致了解了setExpandEntityReferences()方法的功能是对解析XML生成的Document文档进行设置,设置为 true则展开实体引用到生成的文档中替换掉&xxx
的实体引用声明,设置为false则保留实体引用声明的DOM树在生成的文档中。
由于setExpandEntityReferences(false)对Java内置XML解析器的设置起作用前,解析器就已经发起了对外部实体的请求了,故无法防御XXE漏洞!
0x03 思考原因
为何setExpandEntityReferences明明无法防御XXE漏洞,但却很多人在使用呢?当我看了官方JDK API文档之后,发现描述过于简单,从字面上理解很容易与方法的实际功能存在偏差。
初步判断有两个原因:
-
官方文档的描述太过于模糊,很容易让人产生歧义。如果没有跟踪该方法底层实现很容易对它的实际功能理解错误,从而导致错误使用。
-
第一批修复的人应该是看了官方JDK文档来编写修复代码的,之后更多的人是直接百度到了一批人的编写的错误修复代码,直接复制粘贴。导致这个错误的修复方案进一步蔓延。
0x04 参考文章
文章来源于gv7.me:一个被广泛流传的XXE漏洞错误修复方案
4个月前写了一篇文章叫《从代码层面理解java的00截断漏洞》,由于当时出差新疆没时间深入,便在文末立了个有空继续深入的flag。今天我们通过跟踪jdk代码, 彻底搞清楚java中00截断的原理,以及它之后版本是如何修复的? 一、漏洞测试代码改进 看了一些ja…
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论