与Java的序列化机制有关的问题已广为人知。 有效的Java 1st Edition (第10章)和有效的Java 2nd Edition (第11章)的整个最后一章都专门讨论Java的序列化主题。 Effective Java 3rd Edition (第12章)的最后一章仍致力于序列化,但是其中包括一个新项目(Item 85) ,该项目甚至进一步强调了与Java序列化有关的两个断言 :

  • 避免序列化攻击的最佳方法是永远不要反序列化任何东西。
  • 您没有理由在您编写的任何新系统中使用Java序列化。

在最近发布的文档“ 迈向更好的序列化 ”中,Brian Goetz“探讨了改善Java平台中序列化的可能方向。” 尽管本文档的主要目的是为Java序列化提出潜在的新方向,但它只是“一个探索性文档,并不构成任何特定功能的计划。” 这意味着对于Java序列化可能采取的方向来说,这是一个有趣的读物,但是阅读本文档对于Java序列化的总结(当前存在的意义以及我们如何到达此地)具有重要的价值。 这是我其余文章的主题,在本文中我将参考并总结“ 迈向更好的序列化 ”的各个部分,这些部分使我感觉最清楚地阐明了Java序列化机制的当前问题以及我们为什么遇到这些问题。

Goetz在Java序列化的“悖论”中引人注目的段落打开了文档的“动机”部分:


Java的序列化工具有点自相矛盾。 一方面,这可能对Java的成功至关重要-没有它,Java可能不会占据统治地位,因为序列化实现了透明的远程处理,进而实现了Java EE的成功。 另一方面,Java的序列化几乎使每一个错误都可以想象到,并给库维护人员,语言开发人员和用户带来持续的税负(以维护成本,安全风险和缓慢的发展为形式)。

Goetz文档“动机”部分的另一段区分了序列化的一般概念和Java当前的序列化机制的特定设计


需要明确的是,
序列化的概念 ; 将对象转换为可以轻松跨JVM传输并在另一侧重构的形式的能力是一个非常合理的想法。 问题出在
Java中的序列化设计 ,以及它如何适合(或更确切地说,不适合)对象模型。

Goetz指出“ Java的序列化(错误)是多方面的”,他概述了Java序列化设计所犯的“部分罪过”。 我强烈建议阅读原始文档 ,以获取对这些“罪过”的简明和说明性描述,此处仅作总结。

  • “伪装成图书馆的功能,但不是。”

    • “序列化伪装成一个库功能。
  • “假装是静态类型的功能,但不是。”
    • “可序列化性是对象的动态类型的函数,而不是其静态类型的函数。”
  • “编译器无济于事”指出“编写可序列化类时可能犯的各种错误”
  • “魔术方法和字段”是“不影响序列化行为的任何基类或接口指定的”
  • “绝对必要。”
  • “紧密结合到编码。”
  • “不幸的流格式”,“既不紧凑,也不高效,也不可读”。

Goetz还概述了这些Java序列化设计决策的后果(有关每个“严重问题”的更多背景,请参阅原始文档 ):

  • “使图书馆维护者瘫痪。”

    • “库设计人员在发布可序列化的类之前必须非常仔细地考虑-因为这样做可能使您维护与曾经被序列化的所有实例的兼容性。”

“嘲笑封装。”

  • “串行化是您内部状态的无形但公共的构造函数,以及一组无形但公共的访问器。”

在Goetz的“ 迈向更好的序列化 ”文档中,我最喜欢的部分可能是“潜在的错误”部分,因为Goetz在本部分中概述的项目是我编写,阅读和使用的其他Java代码中错误的常见原因。 换句话说,尽管Goetz特别讨论了这些设计决策如何导致Java的序列化机制出现问题,但我(毫无疑问)发现这些通用设计决策也导致了其他领域的问题。

Goetz用以下语句打开“潜在的错误”部分:“上面列出的许多设计错误都来自一个共同的来源-选择通过“魔术”实现序列化,而不是将解构和重建放在对象的第一位。模型本身。” 我发现由其他开发人员甚至我自己编写的“魔术”代码在以后常常令人困惑且难以推理。 我已经明确地意识到,通常最好使用简洁明了的代码。

格茨补充说:“更糟糕的是,魔术尽了最大努力,以使读者看不见。” 当我们第一次实现隐形的“魔术”设计时,它们通常看起来很聪明,但是当他们突然需要对基础魔术的可见性时,使必须阅读,维护和更改代码的开发人员感到非常痛苦。

Goetz引用了Edsger W.Dijkstra的话,并写道:“序列化(目前已实现)与减少程序文本和其计算效果之间的差距完全相反; 我们可能会错误地假设我们的对象总是由类中编写的构造函数初始化而得到原谅,但我们不必如此。

Goetz在“底层错误”部分的结尾处开始了一段,“序列化除了试图变得不可见之外,还尝试做太多事情 。 尽管Goetz专门针对Java的序列化编写了当前的“序列化程序 (而不是仅仅序列化数据 )”的文章,但从更广泛的意义上讲,我已经无数次地看到了这个问题。 对于我们的开发人员来说,设计和实现可以执行某些我们认为可能对某人有用的小功能的代码很诱人,即使绝大多数(或什至所有当前已知的)用户和用例只需要一个简单的子集即可。功能。

鉴于“ 迈向更好的序列化 ”的目标是“探索改善Java平台中序列化的可能方向”,因此文档中涉及到可能影响Java未来序列化机制的设计甚至实现细节的重要细节也就不足为奇了。 此外, Project Amber邮件列表( amber-dev和amber-spec-experts )也对Java序列化的未来发展方向进行了重要讨论。 但是,本文的目的不是看Java序列化的未来,而是着眼于本文档如何很好地总结了Java当前的序列化机制及其历史。

尽管前面提到的Project Amber邮件列表中的消息集中在Java的序列化机制的潜在未来上,但是这些帖子中有关Java当前序列化的一些有趣的评论增加了Goetz在“ 迈向更好的序列化 ”中所总结的内容。 以下是一些最有趣的内容:

  • Goetz在宣布“ 迈向更好的序列化 ” 的帖子中指出,该提案“从根本上解决了序列化的风险”,并“将对象序列化带到了光明的地方,为了确保安全性,必须要这样做。”
  • Brian Goetz的帖子通过暗示重申了当今Java序列化问题的很大一部分是在不调用构造函数的情况下构造对象:“我们的主要安全目标[是允许]反序列化[通过]构造函数进行。”
  • 斯图尔特·马克斯(Stuart Marks)的帖子指出:“提案中关于便利性的推理路线并不是说便利本身就是邪恶的,而是为了追求便利,原始设计采用了语言学机制来实现这一目的。 这削弱了Java平台的某些基础,并直接导致了多个错误和安全漏洞,其中一些是我个人修复的。”
    • Marks概述了一些由于序列化相关的设计决策而导致JDK中细微错误的特定示例。
  • Kevin Bourrillion的帖子指出:“ Java的序列化实现很长一段时间以来一直是一个巨大的伤口”,并补充说“支持其他有线格式的每个框架始终必须从头开始。”

我强烈建议任何对Java序列化感兴趣的人阅读“ 迈向更好的序列化 ”,无论他们的主要兴趣是Java当前的序列化机制还是将来可能变成的东西。 从两个角度来看,这都是一个有趣的文档。

翻译自: https://www.javacodegeeks.com/2019/06/motivations-behind-javas-maligned-serialization.html

Java恶意序列化背后的历史和动机相关推荐

  1. java序列化和反序列化_Java恶意序列化背后的历史和动机

    java序列化和反序列化 与Java的序列化机制相关的问题已广为人知. 有效的Java 1st Edition (第10章)和有效的Java 2nd Edition (第11章)的整个最后一章都专门讨 ...

  2. 最长公共子序列_Java恶意序列化背后的历史和动机

    最长公共子序列 与Java的序列化机制有关的问题已广为人知. Effective Java 1st Edition (第10章)和Effective Java 2nd Edition (第11章)的整 ...

  3. Java的序列化特性将要退出历史舞台了

    甲骨文公司正计划将安全方面的一大棘手难题对象序列化功能从Java当中剔除出去.这项功能亦被称为Java对象序列化,主要用于将对象编码为字节流形式.除了用于轻量化持久性与通过套接字或Java RMI进行 ...

  4. java 对象怎么序列化,java对象序列化总结

    java对象序列化小结 百度百科上介绍序列化是这样的: 序列化 (Serialization): 将对象的状态信息转换为可以存储或传输的形式的过程.在序列化期间,对象将其当前状态写入到临时或持久性存储 ...

  5. java bean 序列化_JAVA bean为何要实现序列化

    简而言之:序列化,就是为了在不同时间或不同平台的JVM之间共享实例对象.即序列化出于两个原因:①.用于持久化到磁盘上:②.用于作为数据流在网络上传输. 所谓的Serializable,就是java提供 ...

  6. java实现序列化_java 序列化实现方式总结

    什么是序列化,可能大家都知道,但又不很清楚,呵呵,就像我一样,下面是一段百度百科的说明,说的很清楚,可以参考下 序列化 (serialization) 将对象的状态信息转换为可以存储或传输的窗体的过程 ...

  7. java图片序列化_Java中的强大武器——对象的序列化

    原标题:Java中的强大武器--对象的序列化 所谓对象序列化就是将对象的状态转换成字节流,以后可以通过这些值再生成相同状态的对象.这个过程也可以通过网络实现,可以先在Windows机器上创建一个对象, ...

  8. 深入分析Java的序列化与反序列化

    阅读目录 Java对象的序列化 如何对Java对象进行序列化与反序列化 序列化及反序列化相关知识 ArrayList的序列化 ObjectOutputStream 总结 序列化是一种对象持久化的手段. ...

  9. fegin调用为什么要序列化_全方位解析Java的序列化

    前言 相信大家日常开发中,经常看到Java对象"implements Serializable".那么,它到底有什么用呢?本文从以下几个角度来解析序列这一块知识点~ 什么是Java ...

最新文章

  1. Python基础10-函数基础
  2. php监听input,jQuery如何实时监听获取input输入框的值
  3. python在linux报错xe6,python出现SyntaxError: Non-ASCII character '\xe6' in file \的错误
  4. jQuery - 获取并设置 CSS 类
  5. Python编程基础:第五十九节 守护线程Daemon Threading
  6. jupyter notebook python插件_VS Code Python 将支持 Jupyter Notebook
  7. 在Mac上为自己手动编译安装一套PHP7的开发环境
  8. Leetcode 110.平衡二叉树
  9. 计算机网络自顶向下方法第6章-链路层和局域网.1
  10. Python爬虫(一)抓取指定的页面
  11. [Canvas]空战游戏进阶 增加发射子弹 敌机中弹爆炸功能
  12. Edraw Max 9.4中文版激活教程
  13. React跨域解决方案
  14. 使用Bitmap font generator工具生成fnt文件
  15. win10计算器rsh_win10计算器rsh_如何打开win10计算器 教你打开win10计算器的方法
  16. mysql explain字段意思解释
  17. Android 实现自动点击屏幕的方法
  18. imx6ul can调试(代码)
  19. (大集合)Linux进程和线程的基本编程、通讯和例程【杂记】
  20. 浅谈GFS之---读写文件流程

热门文章

  1. POJ3263-Tallest Cow【前缀和】
  2. 【模拟】【递归】解压字符串(jzoj 1519)
  3. 2017西安交大ACM小学期 文本查找[AC自动机]
  4. 34、JAVA_WEB开发基础之EL表达式和标签
  5. K8S Learning(5)——Pod
  6. 漫画:什么是鸡尾酒排序
  7. Java(enum)枚举用法详解
  8. 架构师必须掌握的各种编码:ASCII、ISO-8859-1、GB2312
  9. FileDescriptor的作用
  10. 《四世同堂》金句摘抄(十六)