防止反序列创建对象漏洞

******************************************正确写法******************************************************
package com.example.SpringBootTest1.shejimoshi.singleton;
import java.io.ObjectStreamException;
import java.io.Serializable;
public class InnerclassSingleton implements Serializable {
public static final long serialVersionUID = 42L;
private InnerclassSingleton() {
if (InnerclassSingleton.getInstance() != null) {
throw new RuntimeException("单例模式不允许创建多个实例");
}
};

private static class Singleton {
private static final InnerclassSingleton i = new InnerclassSingleton();
}

public static InnerclassSingleton getInstance() {
return Singleton.i;
}

Object readResolve() throws ObjectStreamException {
return InnerclassSingleton.getInstance();
}
}

package com.example.SpringBootTest1.shejimoshi.singleton;
import java.io.*;
public class Test {
public static void main(String[] args) throws IOException, ClassNotFoundException {
InnerclassSingleton instance = InnerclassSingleton.getInstance();
// 序列化
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("testSerializable"));
oos.writeObject(instance);
oos.close();
// 反序列化
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("testSerializable"));
InnerclassSingleton instance2 = (InnerclassSingleton) ois.readObject();
System.out.println(instance == instance2); // true
}
}

package com.example.SpringBootTest1.shejimoshi.singleton;
import java.io.ObjectStreamException;
import java.io.Serializable;
public class InnerclassSingleton implements Serializable {
public static final long serialVersionUID = 42L;
private InnerclassSingleton() {
if (InnerclassSingleton.getInstance() != null) {
throw new RuntimeException("单例模式不允许创建多个实例");
}
};

private static class Singleton {
private static final InnerclassSingleton i = new InnerclassSingleton();
}

public static InnerclassSingleton getInstance() {
return Singleton.i;
}

Object readResolve() throws ObjectStreamException {
return InnerclassSingleton.getInstance();
}
int i = 0; // 新增一行代码
}
package com.example.SpringBootTest1.shejimoshi.singleton;
import java.io.*;
public class Test {
public static void main(String[] args) throws IOException, ClassNotFoundException {
InnerclassSingleton instance = InnerclassSingleton.getInstance();
// 序列化
// ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("testSerializable"));
// oos.writeObject(instance);
// oos.close();
// 反序列化
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("testSerializable"));
InnerclassSingleton instance2 = (InnerclassSingleton) ois.readObject();
System.out.println(instance == instance2); // true (新增了一行代码后打印还是true)
}
}
****************************************非正常写法**************************************
public class InnerclassSingleton implements Serializable {
  // public static final long serialVersionUID = 42L;
private InnerclassSingleton() {
if (InnerclassSingleton.getInstance() != null) {
throw new RuntimeException("单例模式不允许创建多个实例");
}
};

private static class Singleton {
private static final InnerclassSingleton i = new InnerclassSingleton();
}

public static InnerclassSingleton getInstance() {
return Singleton.i;
}

Object readResolve() throws ObjectStreamException {
return InnerclassSingleton.getInstance();
}
}

package com.example.SpringBootTest1.shejimoshi.singleton;
import java.io.*;
public class Test {
public static void main(String[] args) throws IOException, ClassNotFoundException {
InnerclassSingleton instance = InnerclassSingleton.getInstance();
        // 序列化
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("testSerializable"));
oos.writeObject(instance);
oos.close();
// 反序列化
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("testSerializable"));
InnerclassSingleton instance2 = (InnerclassSingleton) ois.readObject();
System.out.println(instance == instance2); // true
}
}

public class InnerclassSingleton implements Serializable {
  // public static final long serialVersionUID = 42L;
private InnerclassSingleton() {
if (InnerclassSingleton.getInstance() != null) {
throw new RuntimeException("单例模式不允许创建多个实例");
}
};

private static class Singleton {
private static final InnerclassSingleton i = new InnerclassSingleton();
}

public static InnerclassSingleton getInstance() {
return Singleton.i;
}

Object readResolve() throws ObjectStreamException {
return InnerclassSingleton.getInstance();
}
int i = 0; // 新增一行代码
}

package com.example.SpringBootTest1.shejimoshi.singleton;
import java.io.*;
public class Test {
public static void main(String[] args) throws IOException, ClassNotFoundException {
InnerclassSingleton instance = InnerclassSingleton.getInstance();
// 序列化
// ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("testSerializable"));
// oos.writeObject(instance);
// oos.close();

// 反序列化
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("testSerializable"));
InnerclassSingleton instance2 = (InnerclassSingleton) ois.readObject();
System.out.println(instance == instance2); // false (由于新增了一行代码,会打印false)
}
}

总结: 如果需要进行网络传输, 需要实现序列化接口, 并且指定一个序列化编号(反序列化时, 尽管类代码有变动, 还是会返回指定编号的对象)
posted @   剑阁丶神灯  阅读(44)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示