1、JSON 注入
JSON注入是指应用程序所解析的JSON数据来源于不可信赖的数据源,程序没有对这些不可信赖的数据进行验证、过滤,如果应用程序使用未经验证的输入构造 JSON,则可以更改 JSON 数据的语义。在相对理想的情况下,攻击者可能会插入无关的元素,导致应用程序在解析 JSON数据时抛出异常。本文以JAVA语言源代码为例,分析“JSON注入”漏洞产生的原因以及修复方法。该漏洞的详细介绍请参见 CWE ID 91: XML Injection (aka Blind XPath Injection) (http://cwe.mitre.org/data/definitions/91.html)。
2、JSON 注入的危害
攻击者可以利用JSON注入漏洞在JSON数据中插入元素,从而允许JSON数据对业务非常关键的值执行恶意操作,严重的可能导致XSS和动态解析代码。
从2018年1月至2019年6月,CVE中共有18条漏洞信息与其相关。部分漏洞如下:
CVE 编号 | 概述 |
---|---|
CVE-2018-7951 | 由于输入验证不充分,某些华为服务器的iBMC(智能基板管理控制器)存在JSON注入漏洞。经过身份验证的远程攻击者可以启动JSON注入来修改管理员的密码。成功利用可能允许攻击者获得系统的管理权限。 |
CVE-2018-7904 | 带有V100R005C00软件的华为1288H V5和288H V5存在JSON注入漏洞。经过身份验证的远程攻击者可以使用JSON注入来修改管理员的密码。由于对输入的验证不充分,可以利用它来获得系统的管理权限。 |
3、示例代码
示例源于 WebGoat-8.0.0.M25 (https://www.owasp.org/index.php/Category:OWASP_WebGoat_Project),源文件名:CSRFFeedback.java。
3.1 缺陷代码
上述示例代码是接收请求参数 feedback 中的 JSON 数据,并将 JSON 数据转换为对象。第35行,声明一个 ObjectMapper 类的实例 objectMapper 用于处理 JSON 数据。第40行在方法 completed 中声明了要获取的参数 feedback,在第42行将请求参数 feedback 的字节数组值和 Map.class 作为参数传入实例 feedback 的 readValue() 方法,用于将 JSON 数据转换为 Map 集合类的对象。
由于 JSON 是根据引号、冒号、逗号和花括号区分各字符意义的,当JSON格式为{“username”:”admin”,”password”:”adminpassword”}时,程序可正确解析该 JSON 数据。数据为{“username”:”admin”,”password”:”admin”password”}时,其中 admin”password 中的引号会破坏整个JSON的结构,导致 JSON 解析失败,无法转换为指定对象。
使用代码卫士对上述示例代码进行检测,可以检出“JSON注入”缺陷,显示等级为高。从跟踪路径中可以分析出数据的污染源以及数据流向,在代码行第42行报出缺陷。如图1所示:
图1:JSON 注入检测示例
3.2 修复代码
在上述修复代码中,使用 com.fasterxml.jackson.core.io 包下的JsonStringEncoder 类来对 JSON 数据进行操作,在第43行获取 JsonStringEncoder 的对象 encoder,调用 quoteAsUTF8 方法将 feedback中的数据按照 JSON 标准处理并编码为 UTF-8,将结果返回为字节数组。将转换后的字节数组作为参数与 Map.class 传入 readValue 方法。使用 JSON 标准对 JSON 数据进行处理,防止 JSON 注入。
使用代码卫士对修复后的代码进行检测,可以看到已不存在“JSON注入”缺陷。如图2所示:
图2:修复后检测结果
4、如何避免 JSON 注入
检查程序逻辑,根据实际需求对数据进行合理过滤和安全校验,以避免产生JSON注入。