java json injection_JSON Injection解决方法

JSON Injection 解决:

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

com.mikesamuel

json-sanitizer

1.0

-----------------------------------------------------------------------------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= newJsonFactory();

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= newJsonFactory();

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();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值