Java原生序列化与反序列化
序列化与反序列化
Java序列化是指把Java对象转换为字节序列的过程;而Java反序列化是指把字节序列恢复为Java对象的过程。
为什么需要序列化?
序列化分为两大部分:序列化和反序列化。序列化是这个过程的第一部分,将数据分解成字节流,以便存储在文件中或在网络上传输。反序列化就是打开字节流并重构对象。对象序列化不仅要将基本数据类型转换成字节表示,有时还要恢复数据。恢复数据要求有恢复数据的对象实例。
序列化为什么会产生安全问题?
只要服务端反序列化数据,客户端传递类的readObject中代码会自动执行,给予攻击者在服务器上运行代码的能力。
Java序列化基本流程
有如下三个文件,Person.java:
import java.io.Serializable;
public class Person implements Serializable {
// 需要实现Serializable接口才可以序列化
private String name;
private int age;
public Person(){
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
",age=" + age +
'}';
}
}
序列化操作,SerializationTest.java:
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class SerializationTest {
public static void serialize(Object obj) throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));
oos.writeObject(obj);
}
public static void main(String[] args) throws Exception{
Person person = new Person("a", 18);
serialize(person);
}
}
反序列化操作,UnserializeTest.java:
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
public class UnserializeTest {
public static Object unserialize(String Filename) throws IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
Object obj = ois.readObject();
return obj;
}
public static void main(String[] args) throws Exception {
Person person = (Person) unserialize("ser.bin");
System.out.println(person);
}
}
SerializationTest中首先生成一个person对象,然后将生成的person对象进行序列化操作,得到二进制文件ser.bin,接着在UnserializeTest中实现反序列化操作得到person对象,并打印出来:
Person{name='a',age=18}
注意:
- (1)想要序列化的对象需要实现Serializable接口才可以序列化。
- (2)使用transient标识的对象不参与序列化。
在Person类中,name属性之前加上transient,改为private transient String name;之后再次尝试序列化和反序列化,输出结果:Person{name='null',age=18}。 - (3)静态成员变量不能被序列化,因为序列化是针对对象的,而静态成员变量属于类。
可能存在反序列化漏洞的形式
- (1)入口类的readObject直接调用危险方法。
Person类文件中重写了readObject方法,在readObject方法中执行命令:
package org.example;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
public class Person implements Serializable {
private transient String name;
private int age;
public Person(){
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
",age=" + age +
'}';
}
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
ois.defaultReadObject();
Runtime.getRuntime().exec("calc");
}
}
再次执行SerializationTest和UnserializeTest实现序列化和反序列化,在反序列化时会调用重写的readObject,从而执行其中的命令,弹出计算器:

(2)入口类参数中包含可控类,该类有危险方法,readObject时调用。
要实现反序列化攻击,入口类最好是继承Serializable,重写readObject,调用常见函数,参数类型宽泛,jdk自带,比如HashMap:

(3)入口类中包含可控类,该类又调用其他有危险的方法的类,readObject时调用。
(4)构造函数/静态代码块等类加载时隐式执行。
Java原生序列化与反序列化的更多相关文章
- java原生序列化和Kryo序列化性能比较
简介 最近几年,各种新的高效序列化方式层出不穷,不断刷新序列化性能的上限,最典型的包括: 专门针对Java语言的:Kryo,FST等等 跨语言的:Protostuff,ProtoBuf,Thrift, ...
- java 对象序列化与反序列化
Java序列化与反序列化是什么? 为什么需要序列化与反序列化? 如何实现Java序列化与反序列化? 本文围绕这些问题进行了探讨. 1.Java序列化与反序列化 Java序列化是指把Java对象转换为 ...
- Java对象序列化与反序列化一 JSON
Java对象序列化与反序列化一 JSON 1. 依赖库 jackson-all-1.6.1.jar 2. 代码 public class Student { private String nam ...
- Java对象序列化和反序列化的工具方法
import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import ja ...
- Java之序列化和反序列化
序列化的对象: package test_demo.SerializableOper; import java.io.Serializable; /* * 序列化对象需要实现序列号接口 * */ pu ...
- java之序列化与反序列化
1.这里主要是介绍Protobuf提供的序列化与反序列化的高效性.相对于传统的java提供的序列化来说,Protobuf的效率提高了很多倍.但是也有不足的地方,就是proto在对象序列化的时候抛弃了很 ...
- Java基础—序列化与反序列化(转载)
转载自: Java序列化与反序列化 1.Java序列化与反序列化 Java序列化是指把Java对象转换为字节序列的过程:而Java反序列化是指把字节序列恢复为Java对象的过程. 2.为什么需要序列化 ...
- Java 中序列化与反序列化
一. 序列化和反序列化概念 Serialization(序列化)是一种将对象以一连串的字节描述的过程:反序列化deserialization是一种将这些字节重建成一个对象的过程.将程序中的对象,放入文 ...
- MessagePack Java Jackson 序列化和反序列化 POJO 为 MessagePack 的数组类型用来与 msgpack-java:0.6 保持兼容性
在 msgpack-java 0.6 或者早期的版本中,POJO 在 MessagePack 中被序列化和反序列化为数组变量. 变量的顺序是基于 Java 类中变量的内部顺序了,这种本来是一种原生的序 ...
- JAVA的序列化与反序列化
一.为什么要进行序列化 再介绍之前,我们有必要先了解下对象的生命周期,我们知道Java对象的生命周期,也即Java中的远程方法调用RMI也会被用到,在网络中要传输对象的话,则必须要对对象进行序列化,关 ...
随机推荐
- Python数组合并和数组分割(数组拆分)
数组的合并和拆分 ## 将数组按照固定长度进行拆分,返回一个二维数组 def list_split(source_list, n): return [source_list[i:i+n] for i ...
- 【调试】pstore原理和使用方法总结
什么是pstore pstore最初是用于系统发生oops或panic时,自动保存内核log buffer中的日志.不过在当前内核版本中,其已经支持了更多的功能,如保存console日志.ftrace ...
- 详解instanceof底层原理,从零手写一个instanceof
壹 ❀ 引 本道题的核心考点还是对于javascript原型的掌握程度,比如__proto__,prototype相关概念,以及instanceof底层原理的理解.若你对于原型已经非常熟悉,那么可以直 ...
- react router component与render有什么区别?提升渲染性能,记一个react router component 误用导致请求死循环的有趣bug
壹 ❀ 引 下午前端大佬突然私聊我,说发现了一个很有趣的bug,问我有没有兴趣,因为我平时会记录一些自认为有意思的问题,所以毫不犹豫就答应了,问题表现如下,当我们系统进入到某个页面下时,接口居然无止境 ...
- NC50428 数星星 Stars
题目链接 题目 题目描述 天空中有一些星星,这些星星都在不同的位置,每个星星有个坐标.如果一个星星的左下方(包含正左和正下)有k颗星星,就说这颗星星是k级的. 例如,上图中星星5是3级的(1,2,4在 ...
- NC25005 [USACO 2008 Ope S]Clear And Present Danger
题目链接 题目 题目描述 Farmer John is on a boat seeking fabled treasure on one of the N (1 <= N <= 100) ...
- Libata Error Message 解析
Libata error messages Contents [hide] 1 Overview 2 Prefix 3 Exception line 4 Input taskfile 5 O ...
- STC12硬件SPI驱动MAX7219点阵LED
max7219是一个用于驱动8位7段数字LED或者8x8点阵LED的驱动芯片, 以列扫描的方式, 用16个pin管理64个发光点, 显示8个数字时刷新率为500-1300Hz, 典型值为800Hz. ...
- Swoole从入门到入土(6)——TCP服务器[粘包]
在了解Swoole下如何处理粘包问题之前,我们需要先了解什么是"粘包".我们以下面这张图进行普及: 假设客户端分别发送了两个数据包D1和D2给服务端,由于服务端一次读取到的字节数是 ...
- 马上就要元宵节了,这里给大家用css端上一碗汤圆
「更多福利资讯查看:2024 首次大厂挑战」. ` .... ` .bowl_wrap{ width: 200px; height: 220px; margin: 100px auto; positi ...