2.6 JSON注入

2.6.1 JSON注入的概念

JSON是一种常见的轻量级数据交换格式,应用程序通常使用JSON来存储数据或传递消息。JSON注入指应用程序解析的JSON数据来源于不可信赖的数据源,程序没有对这些不可信赖的数据进行验证、过滤。若应用程序使用未经验证的输入构造JSON,则可以更改JSON数据的语义。在相对理想的情况下,攻击者可能会插入无关的元素,导致应用程序在解析JSON数据时抛出异常。更为严重的情况下,攻击者可能插入恶意元素对JSON文档、请求或业务中的一些关键值执行可预见的操作。本节分析JSON注入产生的原因、危害以及修复方法。

2.6.2 JSON注入的危害

攻击者可以利用JSON注入漏洞在JSON数据中插入元素,从而允许JSON数据对业务中非常关键的值执行恶意操作,严重时可能出现XSS漏洞和动态解析代码。CVE中也有一些与之相关的漏洞信息,如表2-6所示。

表2-6 与JSON注入相关的漏洞信息

2.6.3 实例代码

本节使用实例的完整源代码可参考本书配套资源文件夹,源文件名:CSRFFeedback.java。

1)缺陷代码

上述代码是接收请求参数feedback中的JSON数据,并将JSON数据转换为对象。在第35行声明一个ObjectMapper类的实例objectMapper用于处理JSON数据,在第39行的completed方法中声明了要获取的参数feedback,在第41行将请求参数feedback的字节数组值和Map.class作为参数传入实例feedback的readValue方法,用于将JSON数据转换为Map集合类的对象。由于JSON是根据引号、冒号、逗号和花括号区分各字符意义的,因此当JSON格式为{"username":"admin","password":"adminpassword"}时,程序可以正确解析该JSON数据;当JSON格式为{"username":"admin","password":"admin"password"}时,其中admin"password中的引号会破坏整个JSON的结构,导致JSON解析失败,无法转换为指定对象。

2)修复代码

上述修复代码使用com.fasterxml.jackson.core.io包的JsonStringEncoder类对JSON数据进行操作,在第41行获取JsonStringEncoder的对象encoder,调用quoteAsUTF8方法将feedback中的数据按照JSON标准处理并编码为UTF-8,将结果返回为字节数组。随后将转换后的字节数组作为参数与Map.class传入readValue方法。使用JSON标准对JSON数据进行处理,防止JSON注入。

2.6.4 如何避免JSON注入

检查程序逻辑,根据实际需求对数据进行合理过滤和安全校验,以避免产生JSON注入。