开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第6天,点击查看活动详情
在OWASP的前10名中,不安全反序列化是一种微妙但危险的应用程序安全威胁。这种命名就恰当的描述了攻击利用了数据序列化,即当一个对象从一个web应用程序传递到另一个web应用程序时发生的“基本的”数据转换过程。在正常情况下,当一个新对象被发送到应用程序时,该对象首先被转换(序列化)为结构化或二进制格式,然后作为顺序的字节流通过网络。在应用程序端,序列化的文件被转换回对象(反序列化)。最常见的是,使用CSV、XML或JSON格式对数据进行序列化。无论使用哪种格式,正确保护这个反序列化过程都是任何开发人员或企业解决设计“难题”的关键部分。
本文的目的是强调不安全的反序列化攻击的危险,并演示可以部署的基于云的安全 API 解决方案,以帮助减轻这种专门针对 JSON 反序列化的威胁。此演示包括使用页面下方提供的代码示例使用 Java 构建 API 调用的分步说明。
不安全反序列化攻击的危险
当攻击者利用不安全的反序列化漏洞时,他们成功地使目标应用程序信任并反序列化恶意对象。此类漏洞通常是攻击者的目标,旨在远程执行 Web 应用程序中的代码,任意读取该应用程序系统中的文件,或导致拒绝服务,从而使应用程序中的网络资源无法为预期用户读取。
在过去五年左右的时间里,JSON 格式在反序列化方面的流行度已经开始超过其同时代格式,部分原因是它作为一种专为数据传输而设计的基于文本的轻量级格式,具有固有的简单性/互操作性,部分原因是它与 JavaScript 的日益流行有着内在的联系,JavaScript 可以在 90% 以上的应用程序中找到的世界网站。随着在整个技术领域使用任何数据格式/工具的日益普及,试图利用该资产的威胁可能会随着时间的推移或多或少成比例地增加,因此,需要额外关注加强该资产的威胁概况。简而言之,JSON 格式的日益普及本身就最好地表明你的 JSON 反序列化工具的安全策略应该定期审查和改进。配置薄弱的 JSON 反序列化工具缺乏足够的数据验证功能,将在反序列化过程中不断面临处理恶意无效文件的危险。当谈到像 JSON 这样的任何流行的、经常被拥护的格式时,很容易陷入一种错误的安全感。
基于云的安全 API 解决方案
增强应用程序对不安全反序列化的威胁配置文件并不是从向反序列化过程中添加新服务开始的。相反,它从仔细分析应用程序信任的反序列化数据开始。如果从应用程序无法控制的外部网络/数据源中提取数据,则应用程序在任何情况下都不应自动反序列化该数据。为了被动地限制这种情况下的威胁,可以部署某些仅处理原始数据类型的序列化工具,从而首先限制进入应用程序的潜在威胁池。如果无法做到这一点,并且所讨论的数据集相对较小,也可以手动查看内存中的 JSON 对象并以这种方式检测差异。然而,无论 JSON 多么容易阅读,这肯定不是一个有效的选择,并且附加到Web 应用程序的精心设计的验证服务将更快更有效地完成同样的任务。即使包含这样的服务,采取额外的基本步骤仍然是标准做法,例如在反序列化过程中记录失败/异常,严格监管所有网络活动(尽可能多),并定期测试反序列化工具以确保他们正在按预期履行职责。
为了帮助使用数据验证服务缓解此漏洞,可以实施免费的 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 响应模型。
{
"Successful": true,
"ContainedJsonInsecureDeserializationAttack": true,
"OriginalInput": "string"
}
实施此 JID 检测 API 是保护常见危险漏洞的一种简单方法。理想情况下,它应该释放你更多的时间和资源来专注于其他重要任务,例如防止其他同样重要的数据安全威胁影响你的系统。威胁有多种形式:包括 SQL 注入、跨站点脚本、服务器端请求伪造等。与以往一样,强烈建议努力研究新的安全解决方案并增加 Web 应用程序的安全策略,以确保数据长期保持安全。