JSON Injection解决方法


 

JSON Injection 解决:

加 JsonSanitizer.sanitize() 进行校验(这个校验貌似可以解决很多Json相关的Fortify Issue);

 

        <dependency>
            <groupId>com.mikesamuel</groupId>
            <artifactId>json-sanitizer</artifactId>
            <version>1.0</version>
        </dependency>

 

 

 

 

-----------------------------------------------------------------------------Issue 描述--------------------------------------------------------------------------------------------------

摘要

该方法将未经验证的输入写入JSON。此调用可能允许攻击者将任意元素或属性注入JSON实体。

说明

JSON注入发生在以下情况下:
1.数据从不受信任的源进入程序。
2.数据被写入JSON流。应用程序通常使用JSON来存储数据或发送消息。当用于存储数据时,JSON通常被视为缓存的数据,
并且可能包含敏感信息。当用于发送消息时,JSON通常与RESTful服务结合使用,并且可以用于传输敏感信息,例如身份验
证凭据。如果应用程序从未经验证的输入构造JSON,则可以更改JSON文档和消息的语义。在相对温和的情况下,攻击者可能
够插入无关的元素,这些元素导致应用程序在解析JSON文档或请求时引发异常。在更严重的情况下,例如涉及JSON注入的情
况,攻击者可能能够插入无关的元素,以允许对JSON文档或请求中的业务关键值进行可预测的操纵。在某些情况下,JSON注入
可能导致跨站点脚本编写或动态代码评估。
示例1:
以下Java代码使用Jackson来从用户控制的输入变量username和$中序列化非特权用户(具有“默认”角色的用户
,而不是具有“ admin”角色的特权用户)的用户帐户身份验证信息。 JSON文件的密码位于 ~/user_info.json:

...
JsonFactory jfactory = new JsonFactory();
JsonGenerator jGenerator = jfactory.createJsonGenerator(new File("~/ user_info.json"), JsonEncoding.UTF8);
jGenerator.writeStartObject();
jGenerator.writeFieldName("username"); jGenerator.writeRawValue("\"" + username + "\"");
jGenerator.writeFieldName("password"); jGenerator.writeRawValue("\"" + password + "\"");
jGenerator.writeFieldName("role"); jGenerator.writeRawValue("\"default\"");
jGenerator.writeEndObject();
jGenerator.close();

 

但是,由于JSON序列化是使用JsonGenerator.writeRawValue()执行的,因此不会验证用户名和密码中不受信任的数
据来转义与JSON相关的特殊字符。这允许用户任意插入JSON密钥,可能会更改序列化JSON的结构。在此示例中,如果非特权用户
使用密码Evil123!在设置用户名变量值的提示符下输入用户名时,在用户名后附加“,” role“:” admin,保存到
〜/ user_info.json的结果JSON将为:

{ 
"username":"mallory",
"role":"admin",
"password":"Evil123!",
"role":"default"
}

 

如果此序列化的JSON文件随后使用Jackson的JsonParser反序列化为HashMap对象,则:

JsonParser jParser = jfactory.createJsonParser(new File("~/user_info.json"));
while (jParser.nextToken() != JsonToken.END_OBJECT) {
String fieldname = jParser.getCurrentName();
if ("username".equals(fieldname)) {
jParser.nextToken();
userInfo.put(fieldname, jParser.getText());
}
if ("password".equals(fieldname)) {
jParser.nextToken();
userInfo.put(fieldname, jParser.getText());
}
if ("role".equals(fieldname)) {
jParser.nextToken();
userInfo.put(fieldname, jParser.getText());
}
if (userInfo.size() == 3)
break;
}
jParser.close();

 

HashMap对象中的用户名,密码和角色密钥的结果值分别为Mallory,Evil123!和admin。如果不进一步验证反序列化的JSON值是否有效,
该应用程序将错误地分配用户Mallory的“ admin”特权。

建议:

将用户提供的数据写入JSON时,应遵循一些准则:
1.不要创建其名称来自用户输入的JSON属性。
2.确保使用安全的序列化功能执行对JSON的所有序列化,该函数在单引号或双引号内定界不受信任的数据,并转义任何特殊字符。
示例2:
以下Java代码实现了与示例1中相同的功能,但是使用JsonGenerator.writeString()而不是JsonGenerator.writeRawValue()
来序列化数据,因此确保正确分隔和转义了所有不受信任的数据:

...
JsonFactory jfactory = new JsonFactory();
JsonGenerator jGenerator = jfactory.createJsonGenerator(new File("~/ user_info.json"), JsonEncoding.UTF8);
jGenerator.writeStartObject();
jGenerator.writeFieldName("username");
jGenerator.writeString(username);
jGenerator.writeFieldName("password");
jGenerator.writeString(password);
jGenerator.writeFieldName("role"); 
jGenerator.writeString("default");
jGenerator.writeEndObject();
jGenerator.close();

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM