通常客户端向服务端发送XML格式请求的数据时,在服务端对数据处理时并不是直接对数据进行处理,而是将XML转换成程序中可操作的对象。在转换时需要用到XStream,XStream可以将对象序列化成XML或将XML反序列化为对象。在使用XStream进行反序列化时,如果程序中没有校验用户输入就进行反序列化处理,那么攻击者可以通过构造恶意输入,让反序列化产生非预期的对象,非预期的对象在创建过程中可能会引发任意代码执行等问题。本文以JAVA语言源代码为例,分析“不安全的反序列化:XStream”漏洞产生的原因以及修复方法。详见 CWE ID 502: Deserialization of Untrusted Data (http://cwe.mitre.org/data/definitions/502.html)。
攻击者可使用“不安全的反序列化:XStream”漏洞,通过修改序列化之后的数据字段,进行提权、越权操作或者替换缓存服务器中的数据,恶意修改服务器数据,严重的可导致远程代码执行问题。
从2019年1月至2019年6月,CVE中共有38条漏洞信息与其相关。部分漏洞如下:
CVE | 概述 |
---|---|
CVE-2019-7091 | ColdFusion版本Update 1,Update 7,Update 15对不受信任的数据进行了反序列化。成功利用可能导致任意代码执行。 |
CVE-2019-4279 | IBM WebSphereApplication Server 8.5和9.0可能允许远程攻击者使用来自不受信任来源的特制序列化对象在系统上执行任意代码。 |
CVE-2019-10912 | Symfony在2.8.50,3.4.26之前的3.x,4.1.12之前的4.x和4.2.7之前的4.2.x,可以缓存可能包含错误用户输入的对象。在序列化或反序列化时,这可能导致删除当前用户有权访问的文件。 |
示例源于 WebGoat-8.0.0.M25 (https://www.owasp.org/index.php/Category:OWASP_WebGoat_Project),源文件名:VulnerableComponentsLesson.java。
上述示例代码是获取到用户输入的 XML 数据并将该数据反序列化为对象,在第54行获取用户输入的 XML 字符串 payload,第57行使用 dom 解析器来构造 XStream 对象 xstream,第58行使用 Contact 类加载器作为 XStream 的类加载器,第60行将 Contact.class配置给 XStream,XStream 可以识别 Contact 类的注解。在第87行调用 fromXML 方法将 XML 字符串 payload 反序列化为 Contact 类的对象 expl。
当以下 XML 文档传入 fromXML 中,将执行 ProcessBuilder 对象实例化,并调用 start()方法从而运行 Windows 计算器。
<contact> <dynamic-proxy> <interface>org.company.model.Contact</interface> <handler class="java.beans.EventHandler"> <target class="java.lang.ProcessBuilder"> <command> <string>calc.exe</string> </command> </target> <action>start</action> <handler> </dynamic-proxy></contact>
使用代码卫士对上述示例代码进行检测,可以检出“不安全的反序列化:XStream”缺陷,显示等级为高。在代码行第87行报出缺陷如图1所示:
图1:”不安全的反序列化: XStream” 检测示例
在上述修复代码中,在第61行调用 allowTypeHierarchy 方法为反序列化类 Contact 添加安全权限避免不安全的反序列化。
使用代码卫士对修复后的代码进行检测,可以看到已不存在“不安全的反序列化:XStream”缺陷。如图2所示:
图2:修复后检测结果
(1) 采用白名单策略,只允许白名单上的对象生成,不允许生成未经定义的对象。
(2) 对序列化对象执行完整性检查和加密处理,防止被恶意篡改和创建恶意对象。
(3) 反序列化过程之前执行严格的类型限制。