Java中JSON注入的Fortify错误
Posted
技术标签:
【中文标题】Java中JSON注入的Fortify错误【英文标题】:Fortify error on JSON Injection in Java 【发布时间】:2018-09-22 19:36:24 【问题描述】:我从客户端获取 SUBSCRIPTION_JSON,我将其转换为字符串,然后使用 gson 库将其设置为模型对象。在 Fortify 安全性上运行代码时,它在下面的代码上给了我 Json 注入错误,并带有以下消息:
这是错误:
On line 159 of ActionHelper.java, the method jsonToObject() writes unvalidated input into JSON. This call could allow an attacker to inject arbitrary elements or attributes into the JSON entity.The method writes unvalidated input into JSON. This call could allow an attacker to inject arbitrary elements or attributes into the JSON entity.
Explanation
JSON injection occurs when:
1. Data enters a program from an untrusted source.
In this case the data enters at getString() in **SubscriptionAction.java** at line 355.
2. The data is written to a JSON stream.
In this case the JSON is written by fromJson() in **ActionHelper.java** at line 159.
SubscriptionAction.java
final String subscriptionJson = subscriptionForm.getString(SUBSCRIPTION_JSON);
ActionHelper.java
public static <T> T jsonToObject(final String jsonString, final Class<T> className)
T object = null;
if (StringUtils.isNotBlank(jsonString))
final Gson gson = (Gson) BeanLocator.getInstance().getBean(GSON);
object = gson.fromJson(jsonString, className);
return object;
SUBSCRIPTION_JSON ->
"subscriptions": [
"attributeId": "1",
"items": [
"strId": "ALL",
"nodeType": "G"
,
"strId": "VO_ENTRY_TIMING_DELAY",
"nodeType": "L"
,
"strId": "O_INVALID",
"nodeType": "L"
,
"strId": "O_LINE_INVALID",
"nodeType": "L"
,
"strId": "V_INVALID",
"nodeType": "L"
,
"strId": "V_ADDRESS_INVALID",
"nodeType": "L"
]
,
"attributeId": "2001",
"items": [
"strId": "OSTBU",
"nodeType": "L"
]
]
【问题讨论】:
【参考方案1】:您必须在将 JSON 转换为 java 对象之前对其进行清理。这是经过测试的解决方案,它删除了这个强化警告。
<dependency>
<groupId>com.mikesamuel</groupId>
<artifactId>json-sanitizer</artifactId>
<version>1.0</version>
</dependency>
InputStream responseBodyAsStream = null;
responseString = EntityUtils.toString(httpResponse.getEntity(),"UTF-8");
String wellFormedJson = com.google.json.JsonSanitizer.sanitize(responseString);
Map map = mapper.readValue(wellFormedJson, Map.class);
Hope this helps..!!
【讨论】:
【参考方案2】:1) 使用“JsonSanitizer.sanitize(string)”。 (这里清理方法的参数是您的 JSON 输入)
2) 要使用 JsonSanitizer 依赖,可以在 pom.xml 中添加如下:
<dependency>
<groupId>com.mikesamuel</groupId>
<artifactId>json-sanitizer</artifactId>
<version>1.2.0</version>
</dependency>
【讨论】:
【参考方案3】:我遇到了同样的问题。您需要清理 json 数据, 通过使用 json-sanitizer 你可以实现它。
在您的项目中添加此依赖项
<dependency>
</dependency>
在你的代码中添加这一行
String newsanitizestring = JsonSanitizer.sanitize(passyourjsondatahere);
现在使用这个字符串newsanitizestring
【讨论】:
【参考方案4】:在将其设置为模型对象之前,您必须验证收到的 json 以确保它完全包含预期的内容。例如,您可以实现一个验证器,该验证器使用预期的字段/格式模式检查 json。
【讨论】:
我该怎么做?我也面临同样的问题。 @BenCheng 您可以在使用字符串之前实现验证器。就像上面的例子一样,它测试字符串是否不同于 null。在那里您可以实现验证器以确保 que json 包含预期的正确键。此外,您还应该考虑如何知道内容来自受信任的来源(例如,在这种环境下,谁能给这个人发送一个随机的 json 给我?)。 @Ben Cheng,你最后是怎么解决这个问题的?我也遇到了同样的问题。 @Derekyy 我没有解决这个问题。 > 我注册了一个自定义反序列化器来检查重复的密钥,但问题仍然存在。我认为 Fortify 无法判断我是否使用自定义反序列化器验证了 json。以上是关于Java中JSON注入的Fortify错误的主要内容,如果未能解决你的问题,请参考以下文章
Fortify漏洞之Dynamic Code Evaluation: Code Injection(动态脚本注入)和 Password Management: Hardcoded Password(密