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

java序列化和反序列化

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

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序列化和反序列化

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/332273.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python元祖迭代_如何在Python中迭代元组的堆栈

我尝试在Python中使用预定义为的DepthFirstSearch类实现DepthFirstSearch算法:class Stack:def __init__(self):self.list []def push(self,item):self.list.append(item)def pop(self):return self.list.pop()def isEmpty(self):return len(self.list) 0我还有一…

Request的学习笔记(属Servlet学习课程)

文章目录获取请求消息数据1.获取请求行的数据2.获取请求头的数据3.获取请求体的数据4.获取其它的数据4.1.获取请求参数的通用方式中文乱码问题4.2.请求转发4.3.共享数据4.4.获取 ServletContext 对象继承与实现体系浏览器访问服务器时,会将用户提交的参数数据、协议…

aws lambda_AWS Lambda事件源映射:使您的触发器混乱无序

aws lambda最近,我们为Sigma Cloud IDE上的无服务器项目引入了两个新的AWS Lambda事件源(触发类型): SQS队列和DynamoDB流 。 (是的,AWS在几个月前就向他们介绍了;但是我们仍然是一个很小的团队…

python curl模块_python pycurl模块

一、pycurl概述PycURl是一个C语言写的libcurl的python绑定库。libcurl 是一个自由的,并且容易使用的用在客户端的 URL 传输库。它的功能很强大,在PyCURL的主页上介绍的支持的功能有:FTP, FTPS, HTTP, HTTPS, GOPHER, TELNET, DICT, FILE and …

MySQL数据库创建用户root@%

步骤: 以 rootlocalhost 登录数据库,即先登录数据库所在的主机,再以 root 用户登录数据库: [roothtlwk0001host ~]# mysql -uroot -p123456必须先删除原来的 root% 用户: mysql> drop user root%; Query OK, 0 r…

第三方工具监控java进程_前9个免费的Java进程监视工具以及如何选择一种

第三方工具监控java进程这样就可以运行Java代码了。 也许它甚至可以在生产服务器上运行。 当您做好工作后,我们得到了好消息和令人讨厌的消息。 令人讨厌的消息是,现在开始调试。 就是进行调试和应用程序性能监视。 这意味着您不仅需要查看编写的代码&a…

python中的numpy函数算相关系数_NumPy ufunc通用函数

NumPy 提供了两种基本的对象,即 ndarray 和 ufunc 对象。前面几节已经介绍了 ndarray,本节将介绍 Numpy。ufunc 是 universal function 的缩写,意思是“通用函数”,它是一种能对数组的每个元素进行操作的函数。许多 ufunc 函数都是…

MySQL 8.x 以前的版本修改密码规则

查看密码相关变量: mysql> show variables like validate_password%; ---------------------------------------------- | Variable_name | Value | ---------------------------------------------- | validate_password_dictionary_f…

aws mfa 认证_如何为您的AWS账户设置多因素身份验证(MFA)

aws mfa 认证第1步 : 转到AWS控制台并使用您的用户名密码登录。 第2步 : 转到服务-> IAM 第三步: 单击您的根帐户上的激活MFA 第4步 : 在步骤3中,点击屏幕上的管理MFA按钮。 步骤5: 单击分配…

python具体工作内容_有没有人知道公司里用python工作的内容有什么

2018-07-11 回答python的特色 简单 python是一种代表简单主义思想的语言。阅读一个良好的python程序就感觉像是在读英语一样,尽管这个英语的要求非常严格!python的这种伪代码本质是它最大的优点之一。它使你能够专注于解决问题而不是去搞明白语言本身。 …

如何导入hadoop源码到eclipse

需要进一步学习hadoop、需要看看内部源码实现,因此需要将hadoop源码导入都eclipse中。 简单总结一下,具体步骤如下: 首先确保已经安装了git、maven3、protobuf2.5、如果没有安装需要提前安装一下 0、preliminary linux distribution(我的…

线程池的学习

文章目录线程池原理JDK 1.5 之后提供的线程池工厂类线程池的使用步骤线程池原理 1.创建多个线程对象,存放到集合中,集合可以是 ArrayList 或者 LinkedList 2.从集合中取出一个线程对象,执行指定的任务 3.一个线程对象只能执行一个任务&#…

javafx 界面_JavaFX的科幻用户界面第1部分

javafx 界面使用JavaFX创建的Sci-Fi UI成形窗口 虚构的UI可以变成现实吗? 成长于80年代的小时候,我看到了自己的科幻电影,这确实激发了我对图形用户界面(GUI)的热爱,尤其是试图使科幻UI在现实世界中成为可…

token验证_如何利用 C# 爬取带 Token 验证的网站数据?

在对文本数据的情感分析中,基于情感词典的方法是最简单也是最常用的一种了。它的大体思路如下:对文档分词,找出文档中的情感词、否定词以及程度副词,然后判断每个情感词之前是否有否定词及程度副词,将它之前的否定词和…

hadoop2.6.0+eclipse配置

【0】安装前的声明 0.1) 所用节点2个 master : 192.168.119.105 hadoop5 slave : 192.168.119.101 hadoop1 (先用一个slave,跑成功后,在从master分别scp到各个slaves即可】) 0.2) 每个机子的那些个文件…

线程同步的学习

文章目录一、同步代码块二、同步方法静态同步方法三、Lock解决线程安全问题的三种方案:同步代码块、同步方法、使用 Lock一、同步代码块 synchronized(同步锁对象) { 需要同步操作的代码 }注: 1.锁对象可以是任意对象 2.必须保证多个线程使用同一个锁对…

spock测试_用于混合Spock 1.x和JUnit 5测试的Maven项目设置

spock测试我为Maven创建了一个示例Groovy项目,该项目在一个项目中混合了Spock测试和JUnit 5测试。 在下一节中,我将描述如何设置这种Maven项目。 在项目中启用Groovy 首先,您必须在项目中启用Groovy。 一种可能性是将GMavenPlus插件添加到您…

python 图片识别_python识别图片文字

滑稽研究所python识别图片文字哈喽,大家好呀,我是滑稽君。大家在写论文时可能经常碰到无法复制文字的文章。明明找到了需要的内容却无法直接复制使用,这让我们十分苦恼。那么本期滑稽君就告诉大家如何使用python识别图片中的文字。滑稽君整理…

MySQL数据库的数据类型decimal详解

大概意思是这样的: decimal(m,d) m是数字的最大位数,他的范围是从1-65; d是小数点后的位数,他的范围是0-30,并且不能大于m。 如果m被省略了,那么m的值默认为10, 如果d被省略了,那么d…

如何撰写论文

【0】README 0.1)本内容转自一个学长的口述,该学长在硕士期间发表论文6篇,现在 某高校读博; 0.2)鉴于看的人比较多,于今日对文本进行排版便于各位阅读(timestamp: 1512141116)&…