Java服务XXE漏洞防御方法

前段时间在搞应急,从一个啥都不会的小白学了一些XXE的简单poc构造和防御手段,网上攻击的poc很多,就不多说了,防御方法五花八门,而且有些防御根本就是无效的!!写篇文章分享一下,如何用Java彻底防御XXE。

一、简介

Java提供了一些解析xml的API,也有第三方写的,如果攻击者构造恶意的xml让Java应用去解析,可以造成任意文件读。在Java里是无法代码执行的,但在其他语言里可能会。

最全的链接是这个 https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Prevention_Cheat_Sheet#JAXB_Unmarshaller

(但经过测试,大部分写的不错,漏了一些细节,也就有了这篇文章)

Github地址

https://github.com/LeadroyaL/java-xxe-defense-demo

本文原本写于2018年 8 月,很多不准确的地方,建议阅读2019 年 7 月的两篇文章,个人认为更加清晰和准确,链接为http://www.leadroyal.cn/?p=930
http://www.leadroyal.cn/?p=914

 

二、各种写法

1、DocumentBuilderFactory

官方patch

但其实只有第一句是生效的,后面那段没什么鬼用的,不信的话可以把第一句去掉,该日的照样可以日。(删除于 19 年 7 月)

可以使用本文最后的poc1来验证。如果出现了网络上的卡顿、或者文件NotFound,就说明仍然可以被攻击,如果出现了抛出异常,就是成功防御。

另一种patch方式:

使用这个Feature也是比较保险的方式,后面会讲我是如何找到这个Feature的,也是很巧合。

民间的垃圾patch

只写这句没用的,照样可以被日。

2、SAXBuilder

官方patch

这个没什么好讲的,用poc1验证即可,应该也是第一句最重要,后面两句用处不是很大

3、SAXParserFactory

官方patch

使用poc1来验证。

其实可以多加两句,可能更安全一点(删除于 19 年 7 月)

民间流行的垃圾patch

4、SAXReader

官方patch

使用poc1来验证。

5、SAXTransformFactory

官方patch

使用poc1来验证。

6、SchemaFactory

官方patch

使用poc1来验证。

7、TransformFactory

官方patch

使用poc1来验证。

8、Validator

官方patch

使用poc1来验证。

9、XMLInputFactory

官方patch

使用poc1来验证。

10、XMLReader

官方patch

使用poc1来验证。

11、unmarshaller的操作

Unmarshaller的一般需要提供一个class,对其中的对象进行自动的编码和解码,所以没有通用的poc,需要和其他类进行配合。在实际使用场景中,为了防止自己写错,可以先marshall一份String,再将这个String unmarshall回去。

例如:

这个类和xmlString可以相互转化,那么poc构造时候,就要使用第二种,见末尾。

一般 unmarshall 是从上文的类里分出来的,只要工厂类设置好feature,这里就不会出事。

12、额外JAXBContext,自带防御。

这个虽然没有设置过feature,但也是无法被日的,就是因为JAXBContext里在创建unmarshaller的时候,某句话,设置了secure-processing的Feature。

使用poc2来验证。

附:poc1

附:poc2

13、dom4j低版本自带的XXE(2018.11更新)

处理线上风险时,不小心看到了这个 API,我写的扫描器扫出来的,准备去官网报个洞,发现被人报了。

https://github.com/dom4j/dom4j/issues/28

很简单, DocumentHelper.parseText() 里直接用了 SaxReader,没有做保护。

方案有两个:一是升级版本,升级到2.1.1即可;二是重构代码,不要用这个 API。

注意,从1.x到2.x的过程,官方改名了!

1.x 是 dom4j:dom4j ;2.x是 org.dom4j:dom4j

三、Tips

1、如果是一些工厂类的话,一定要先设置Feature,再去生成数据。例如下面两种写法,后者是无效的。

2、觉得防御好后,记得测一下,不然很容易被网上的一些垃圾patch给坑了。

四、相关链接

https://blog.spoock.com/2018/10/23/java-xxe/ 后来的另一篇介绍xxe的,比我这篇更清晰。


=============================================================
随着访客的增多,LeadroyaL在本站流量的开支越来越多了,曾经1元能用1个月,现在1元只能用3天。如果觉得本文帮到了你,希望能够为服务器的流量稍微打赏一点,谢谢!

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*

code