如何用Java检查JSON不安全的反序列化(JID)攻击
不安全的反序列化是一种常见而危险的网络应用程序安全威胁。通过加入JID检测API来提高你的威胁程度。
不安全的反序列化一直被列入OWASP的前十名,是一种微妙但危险的应用安全威胁。 这种命名恰当的攻击利用了数据序列化,即当一个对象从一个Web应用传递到另一个应用时发生的 "面包和黄油 "数据转换过程。 在正常情况下,当一个新的对象被发送到一个应用程序时,该对象首先被转换(序列化)为结构化或二进制格式,然后作为一个连续的字节流通过网络。 在应用的一端,序列化的文件在被应用解释之前被转回为一个对象(反序列化)。最常见的是,这些数据是用CSV、XML或JSON格式序列化的。 无论使用哪种格式,正确保护这个反序列化过程是任何个人开发者或企业需要解决的设计 "难题 "的关键部分。
本文的目的是强调不安全的反序列化攻击的危险性,并演示一个基于云的安全API解决方案,该解决方案可以被部署,以帮助减轻这种威胁,特别是针对JSON反序列化。 该演示包括使用页面下方提供的代码示例,用Java构建你的API调用的分步说明。
不安全的反序列化攻击的危险性
当攻击者利用不安全的反序列化漏洞时,他们成功地使目标应用程序信任并反序列化了一个恶意对象。这类漏洞通常是攻击者的目标,目的是在网络应用中远程执行代码,任意读取该应用系统中的文件,或造成拒绝服务,使应用中的网络资源对其目标用户无法读取。 2017年,一个不安全的反序列化攻击的明显例子是针对一家大型信用报告公司,利用了一个脆弱的REST网络服务,悄悄地能够反序列化包含远程命令的恶意对象。由于这次攻击,属于数百万美国人的敏感信息被暴露出来,由于对该公司安全政策的信任减弱,公司股价下跌了13%。
在过去的半个多世纪里,JSON格式已经开始在反序列化方面超过其同时代的格式,部分原因是它作为一种专门为数据传输设计的轻量级、基于文本的格式所具有的固有的简单性/互操作性,部分原因是它与不断增长的JavaScript的内在联系,世界上90%以上的网站都可以找到它。 随着任何数据格式/工具在整个技术领域的使用日益普及,试图利用该资产的威胁可能会随着时间的推移或多或少地增加,因此,需要额外关注加强该资产的威胁状况。 显然,JSON格式的日益普及本身就是最好的说明,你的JSON反序列化工具的安全策略应该定期审查和改进。 配置薄弱的JSON反序列化工具如果缺乏足够的数据验证功能,在反序列化过程中就会不断有处理恶意的无效文件的危险。 当涉及到任何像JSON这样流行的、经常被推崇的格式时,很容易陷入一种错误的安全感。
基于云的安全API解决方案
然而,提高你的应用程序对不安全的反序列化的威胁程度,并不是从向你的反序列化过程添加新的服务开始。 相反,它始于仔细分析你的应用程序信任的反序列化的数据。如果你从外部网络/数据源提取数据,而你的应用程序又不在控制范围内,那么你的应用程序在任何情况下都不应该自动反序列化这些数据。 为了被动地限制这种情况下的威胁,可以部署某些只处理原始数据类型的序列化工具,首先限制进入你的应用程序的潜在威胁库。 当这不可能时,当有关的数据集相对较小时,你可以选择在内存中手动审查JSON对象,并通过这种方式检测差异。然而,无论JSON多么容易阅读,这肯定不是一个有效的选择,一个精心设计的验证服务附属于你的网络应用程序将更快速有效地完成同样的任务。 即使包含了这样的服务,也应该采取额外的基本措施,如记录反序列化过程中的失败/异常,严格控制所有的网络活动(尽可能),并定期测试反序列化工具,以确保它们按计划履行职责。
为了帮助你用数据验证服务缓解这个漏洞,你可以实现一个免费的Cloudmersive Security API,它可以检测不安全的JSON对象,并提供一个布尔值,验证是否存在攻击(或没有攻击)。 有了这个JSON不安全反序列化(JID)API的保护,你的JSON反序列化工具将具备在反序列化过程发生之前在内存中快速检测JID攻击的能力,使基于JSON的威胁失去活力,避免你的系统受到潜在的破坏。 以下演示的目的是向你展示如何基于预先格式化的、可随时运行的Java代码实例来实现这个JID检测API。我在这些代码片段周围添加了一些额外的文档,描述了如何正确满足你进行这个API调用所需的基本参数。
示范
实现该API的第一步是安装Maven SDK。 要做到这一点,首先要在pom.xml中为仓库添加一个jitpack引用。
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
完成后,在pom.xml中添加对该依赖的引用:
<dependencies>
<dependency>
<groupId>com.github.Cloudmersive</groupId>
<artifactId>Cloudmersive.APIClient.Java</artifactId>
<version>v4.25</version>
</dependency>
</dependencies>
现在你可以使用下面的示例代码来构造API调用,首先添加Import classes 。 不过,在调用API之前,你要确保准备好两个必要的参数。 这些参数包括
- 你的JSON对象字符串
- 你的Cloudmersive API密钥(通过注册一个免费账户获得一个密钥;你的密钥将提供每月800次的API调用限制)
// Import classes:
//import com.cloudmersive.client.invoker.ApiClient;
//import com.cloudmersive.client.invoker.ApiException;
//import com.cloudmersive.client.invoker.Configuration;
//import com.cloudmersive.client.invoker.auth.*;
//import com.cloudmersive.client.ContentThreatDetectionApi;
ApiClient defaultClient = Configuration.getDefaultApiClient();
// Configure API key authorization: Apikey
ApiKeyAuth Apikey = (ApiKeyAuth) defaultClient.getAuthentication("Apikey");
Apikey.setApiKey("YOUR API KEY");
// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
//Apikey.setApiKeyPrefix("Token");
ContentThreatDetectionApi apiInstance = new ContentThreatDetectionApi();
String value = "value_example"; // String | User-facing text input.
try {
StringInsecureDeserializationJsonDetection result = apiInstance.contentThreatDetectionDetectInsecureDeserializationJsonString(value);
System.out.println(result);
} catch (ApiException e) {
System.err.println("Exception when calling ContentThreatDetectionApi#contentThreatDetectionDetectInsecureDeserializationJsonString");
e.printStackTrace();
}
在成功进行API调用后,你会收到一个近乎即时的响应,让你知道操作是否成功,以及有关对象是否包含一个JSON反序列化攻击。 下面,我提供了一个API响应模型。
JSON
{
"Successful": true,
"ContainedJsonInsecureDeserializationAttack": true,
"OriginalInput": "string"
}
实现这个JID检测API是保护一个常见的、危险的漏洞的一个简单方法。理想情况下,它应该释放出更多的时间和资源来关注其他重要的任务,例如防止其他同样令人担忧的数据安全威胁影响你的系统。这种威胁有多种形式;你的应用程序漏洞列表中的其他常见补充可能包括像SQL注入、跨网站脚本、服务器端请求伪造等。 与以往一样,强烈建议努力研究新的安全解决方案并增加你的网络应用程序的安全策略,以确保你的数据长期保持安全。