【AICon】探索RAG 技术在实际应用中遇到的挑战及应对策略!AICon精华内容已上线73%>>> 了解详情
写点什么

Java 序列化的状态

  • 2018-09-10
  • 本文字数:6034 字

    阅读完需:约 20 分钟

关键要点

  • Java 序列化在很多库中引入了安全漏洞。
  • 对序列化进行模块化处于开放讨论状态。
  • 如果序列化能够成为模块,开发人员将能够将其从攻击表面上移除。
  • 移除其他模块可以消除它们所带来的风险。
  • 插桩提供了一种编织安全控制的方法,提供现代化的防御机制。

多年来,Java 的序列化功能饱受安全漏洞 zero-day 攻击,为此赢得了“持续奉献的礼物”和“第四个不可饶恕的诅咒”的绰号。

作为回应,OpenJDK 贡献者团队讨论了一些用于限制序列化访问的方法,例如将其提取到可以被移除的jigsaw 模块中,让黑客无法攻击那些不存在的东西。

一些文章(例如“序列化必须死”)提出了这样的建议,将有助于防止某些流行软件(如VCenter 6.5)的漏洞被利用

什么是序列化?

自从 1997 年发布 JDK 1.1 以来,序列化已经存在于 Java 平台中。

它用于在套接字之间共享对象表示,或者将对象及其状态保存起来以供将来使用(反序列化)。

在 JDK 10 及更低版本中,序列化作为 java.base 包和 java.io.Serializable 方法的一部分存在于所有的系统中。

GeeksForGeeks 对序列化的工作原理进行了详细的描述。

有关更多如何使用序列化的代码示例,可以参看 Baeldung 对 Java 序列化的介绍

序列化的挑战和局限

序列化的局限主要表现在以下两个方面:

  1. 出现了新的对象传输策略,例如 JSON、XML、Apache Avro、Protocol Buffers 等。
  2. 1997 年的序列化策略无法预见现代互联网服务的构建和攻击方式。

进行序列化漏洞攻击的基本前提是找到对反序列化的数据执行特权操作的类,然后传给它们恶意的代码。为了理解完整的攻击过程,可以参看 Matthias Kaiser 在 2015 年发表的“ Exploiting Deserialization Vulnerabilities in Java ”一文,其中幻灯片第 14 页开始提供了相关示例。

其他大部分与序列号有关的安全研究都是基于Chris Frohoff、Gabriel Lawrence 和Alvaro Munoz 的工作成果。

序列化在哪里?如何知道我的应用程序是否用到了序列化?

要移除序列化,需要从 java.io 包开始,这个包是 java.base 模块的一部分。最常见的使用场景是:

使用这些方法的开发人员应考虑使用其他存储和读回数据的替代方法。Eishay Smith 发布了几个不同序列化库的性能指标。在评估性能时,需要在基准度量指标中包含安全方面的考虑。默认的Java 序列化“更快”一些,但漏洞也会以同样的速度找上门来。

我们该如何降低序列化缺陷的影响?

项目Amber 包含了一个关于将序列化API 隔离出来的讨论。我们的想法是将序列化从java.base 移动到单独的模块,这样应用程序就可以完全移除它。在确定 JDK 11 功能集时并没有针对该提议得出任何结果,但可能会在未来的 Java 版本中继续进行讨论。

通过运行时保护来减少序列化暴露

一个可以监控风险并自动化可重复安全专业知识的系统对于很多企业来说都是很有用的。Java 应用程序可以将 JVMTI 工具嵌入到安全监控系统中,通过插桩的方式将传感器植入到应用程序中。Contrast Security 是这个领域的一个免费产品,它是 JavaOne 大会的 Duke's Choice 大奖得主。与其他软件项目(如 MySQL 或 GraalVM)类似, Contrast Security 的社区版对开发人员是免费的。

将运行时插桩应用在 Java 安全性上的好处是它不需要修改代码,并且可以直接集成到 JRE 中。

它有点类似于面向切面编程,将非侵入式字节码嵌入到源端(远程数据进入应用程序的入口)、接收端(以不安全的方式使用数据)和转移(安全跟踪需要从一个对象移动到另一个对象)。

通过集成每个“接收端”(如 ObjectInputStream),运行时保护机制可以添加额外的功能。在从 JDK 9 移植反序列化过滤器之前,这个功能对序列化和其他攻击的类型(如 SQL 注入)来说至关重要。

集成这个运行时保护机制只需要修改启动标志,将 javaagent 添加到启动选项中。例如,在 Tomcat 中,可以在 bin/setenv.sh 中添加这个标志:

CATALINA_OPTS=-javaagent:/Users/ecostlow/Downloads/Contrast/contrast.jar

启动后,Tomcat 将会初始化运行时保护机制,并将其注入到应用程序中。关注点的分离让应用程序可以专注在业务逻辑上,而安全分析器可以在正确的位置处理安全性。

其他有用的安全技术

在进行维护时,可以不需要手动列出一长串东西,而是使用像 OWASP Dependency-Check 这样的系统,它可以识别出已知安全漏洞的依赖关系,并提示进行升级。也可以考虑通过像 DependABot 这样的系统进行库的自动更新。

虽然用意很好,但默认的 Oracle 序列化过滤器存在与 SecurityManager 和相关沙箱漏洞相同的设计缺陷。因为需要混淆角色权限并要求提前了解不可知的事物,限制了这个功能的大规模采用:系统管理员不知道代码的内容,所以无法列出类文件,而开发人员不了解环境,甚至 DevOps 团队通常也不知道系统其他部分(如应用程序服务器)的需求。

移除未使用模块的安全隐患

Java 9 的模块化 JDK 能够创建自定义运行时镜像,移除不必要的模块,可以使用名为jlink 的工具将其移除。这种方法的好处是黑客无法攻击那些不存在的东西。

从提出模块化序列化到应用程序能够实际使用以及使用其他序列化的新功能需要一段时间,但正如一句谚语所说:“种树的最佳时间是二十年前,其次是现在”。

剥离 Java 的原生序列化功能还应该为大多数应用程序和微服务提供更好的互操作性。通过使用标准格式(如 JSON 或 XML),开发人员可以更轻松地在使用不同语言开发的服务之间进行通信——与 Java 7 的二进制 blob 相比,python 微服务通常具有更好的读取 JSON 文档的集成能力。不过,虽然 JSON 格式简化了对象共享,针对 Java 和.NET 解析器的“ Friday the 13th JSON attacks ”证明了银弹是不存在的(白皮书)。

在进行剥离之前,序列化让然保留在 java.base 中。这些技术可以降低与其他模块相关的风险,在序列化被模块化之后,仍然可以使用这些技术。

为 Apache Tomcat 8.5.31 模块化 JDK 10 的示例

在这个示例中,我们将使用模块化的 JRE 来运行 Apache Tomcat,并移除任何不需要的 JDK 模块。我们将得到一个自定义的 JRE,它具有更小的攻击表面,仍然能够用于运行应用程序。

确定需要用到哪些模块

第一步是检查应用程序实际使用的模块。OpenJDK 工具 jdeps 可以对 JAR 文件的字节码执行扫描,并列出这些模块。像大多数用户一样,对于那些不是自己编写的代码,我们根本就不知道它们需要哪些依赖项或模块。因此,我使用扫描器来检测并生成报告。

列出单个 JAR 文件所需模块的命令是:

jdeps -s JarFile.jar

它将列出模块信息:

tomcat-coyote.jar -> java.base
tomcat-coyote.jar -> java.management
tomcat-coyote.jar -> not found

最后,每个模块(右边的部分)都应该被加入到一个模块文件中,成为应用程序的基本模块。这个文件叫作 module-info.java,文件名带有连字符,表示不遵循标准的 Java 约定,需要进行特殊处理。

下面的命令组合将所有模块列在一个可用的文件中,在 Tomcat 根目录运行这组命令:

find . -name *.jar ! -path "./webapps/*" ! -path "./temp/*" -exec jdeps -s {} \; | sed -En "s/.* -\> (.*)/  requires \1;/p" | sort | uniq | grep -v "not found" | xargs -0 printf "module com.infoq.jdk.TomcatModuleExample{\n%s}\n"

这组命令的输出将被写入 lib/module-info.java 文件,如下所示:

module com.infoq.jdk.TomcatModuleExample{
  requires java.base;
  requires java.compiler;
  requires java.desktop;
  requires java.instrument;
  requires java.logging;
  requires java.management;
  requires java.naming;
  requires java.security.jgss;
  requires java.sql;
  requires java.xml.ws.annotation;
  requires java.xml.ws;
  requires java.xml;
}

这个列表比整个 Java 模块列表要短得多。

下一步是将这个文件放入 JAR 中:

javac lib/module-info.java
jar -cf lib/Tomcat.jar lib/module-info.class

最后,为应用程序创建一个 JRE:

jlink --module-path lib:$JAVA_HOME/jmods --add-modules ThanksInfoQ_Costlow --output dist

这个命令的输出是一个运行时,包含了运行应用程序所需的恰到好处的模块,没有任何性能开销,也没有了未使用模块中可能存在的安全风险。

与基础 JDK 10 相比,只用了 98 个核心模块中的 19 个。

java --list-modules

com.infoq.jdk.TomcatModuleExample
java.activation@10.0.1
java.base@10.0.1
java.compiler@10.0.1
java.datatransfer@10.0.1
java.desktop@10.0.1
java.instrument@10.0.1
java.logging@10.0.1
java.management@10.0.1
java.naming@10.0.1
java.prefs@10.0.1
java.security.jgss@10.0.1
java.security.sasl@10.0.1
java.sql@10.0.1
java.xml@10.0.1
java.xml.bind@10.0.1
java.xml.ws@10.0.1
java.xml.ws.annotation@10.0.1
jdk.httpserver@10.0.1
jdk.unsupported@10.0.1

运行这个命令后,就可以使用 dist 文件夹中的运行时来运行应用程序。

看看这个列表:部署插件(applet)消失了,JDBC(SQL)消失了,JavaFX 也不见了,很多其他模块也消失了。从性能角度来看,这些模块不再产生任何影响。从安全角度来看,黑客无法攻击那些不存在的东西。保留应用程序所需的模块非常重要,因为如果缺少这些模块,应用程序也无法正常运行。

关于作者

Erik Costlow 是甲骨文的 Java 8 和 9 产品经理,专注于安全性和性能。他的安全专业知识涉及威胁建模、代码分析和安全传感器增强。在进入技术领域之前,Erik 是一位马戏团演员,可以在三轮垂直独轮车上玩火。

查看英文原文 The State of Java Serialization

2018-09-10 18:222506
用户头像

发布了 731 篇内容, 共 432.3 次阅读, 收获喜欢 1997 次。

关注

评论

发布
暂无评论
发现更多内容

选择优质的led透明屏的7个步骤

Dylan

产品、 LED显示屏 售后服务

中企出海困难重重?海外税务数字化解决方案来支招!

用友BIP

中企出海

对编程语言中错误处理机制的思考

宇宙之一粟

错误处理 6 月 优质更文活动

顶象发布《车企App安全研究白皮书》,剖析车企App两大风险

说山水

旺链科技赋能泳池卫士守护人身安全

旺链科技

区块链 泳池安全 泳池卫士

一份配置轻松搞定表单渲染,配置式表单渲染器在袋鼠云的实现思路与实践

袋鼠云数栈

大数据 企业号 6 月 PK 榜

数智人力领域的“chat GPT”,让人才发现更简单更智能

用友BIP

数智人力

【Netty】「NIO」(三)剖析 Selector

sidiot

Java 后端 Netty 6 月 优质更文活动

前端AST详解,手写babel插件

不叫猫先生

6 月 优质更文活动

vue2.x与vue3.x中自定义指令详解

不叫猫先生

Vue 自定义指令

Vue3项目中Pinia状态管理工具的使用

不叫猫先生

Vue Pinia 6 月 优质更文活动

前端内存泄漏详解

不叫猫先生

内存泄露 6 月 优质更文活动

深度学习应用篇-计算机视觉-图像分类[2]:LeNet、AlexNet、VGG、GoogleNet、DarkNet模型结构、实现、模型特点详细介绍

汀丶人工智能

人工智能 深度学习 计算机视觉 图像分类 6 月 优质更文活动

GaussDB(DWS)查询过滤器原理与应用

华为云开发者联盟

数据库 华为云 华为云开发者联盟 企业号 6 月 PK 榜

阿里云丁宇:云上开发成为主流,Serverless 定义新范式

阿里巴巴云原生

阿里云 Serverless 云原生

深入理解注解驱动配置与XML配置的融合与区别

华为云开发者联盟

开发 华为云 华为云开发者联盟 企业号 6 月 PK 榜

数智人力:现代企业解决人才短缺的新途径

用友BIP

数智人力

【JavaScript】手写Promise

不叫猫先生

JavaScript Promise 6 月 优质更文活动

Vue项目中实现ElementUI按需引入

不叫猫先生

Vue Element UI 按需加载 6 月 优质更文活动

【云原生】Docker的基本使用方法与优势

不叫猫先生

Docker 6 月 优质更文活动

苹果WWDC 2023发布会总结

楚少AI

wwdc WWDC 2023 苹果wwdc2023

大学共享电单车合作投放准备工作

共享电单车厂家

共享电动车厂家 共享电单车投放 共享电动车合作 校内共享电动车

数字经济快速发展下企业需要什么样的数智平台?

用友BIP

企业数智化 数智平台

聚焦数智人力,让员工“跳槽”不再尴尬!

用友BIP

人力资源 数智人力

直播预告 | 一体化智能可观测平台如何保障电商节大促

博睿数据

可观测性 智能运维 博睿数据 电商节

【热点追踪】从价值到架构,走近全新升级的阿里云 Serverless 容器服务 ASK

阿里巴巴云原生

阿里云 Serverless 容器 云原生

人工智能创新挑战赛:海洋气象预测Baseline[4]完整版(TensorFlow、torch版本)含数据转化、模型构建、MLP、TCNN+RNN、LSTM模型训练以及预测

汀丶人工智能

人工智能 数据挖掘 深度学习 LSTM 6 月 优质更文活动

vue2.x,vue3.x使用provide/inject注入区别

不叫猫先生

Vue 6 月 优质更文活动

中企出海,数智人力重构企智人效的人才供应体系

用友BIP

人力资源 中企出海 数智人力

亚信科技AntDB数据库荣获赛宝优选信创优秀解决方案奖

亚信AntDB数据库

AntDB AntDB数据库 企业号 6 月 PK 榜

云上数据库:从零到壹的实践经验分享

科技热闻

Java序列化的状态_Java_Erik Costlow_InfoQ精选文章