无题
- 通过反射
/**
* 如何防止反射漏洞
* @author admin
*
*/
public class CrackSingleton {
public static void main(String[] args) throws Exception{
SingletonPattern06 s=SingletonPattern06.getInstance();
System.out.println(s);
//通过反射的方法直接调用私有的构造器————>空构造器添加判断
Class<SingletonPattern06> clz=(Class<SingletonPattern06>)Class.forName("com.fgy.singleton.SingletonPattern06");
Constructor<SingletonPattern06> c=clz.getDeclaredConstructor(null);
c.setAccessible(true);
SingletonPattern06 s1=c.newInstance();
SingletonPattern06 s2=c.newInstance();
System.out.println(s1);
System.out.println(s2);
控制台:
com.fgy.singleton.SingletonPattern06@6bbc4459
com.fgy.singleton.SingletonPattern06@5d888759
com.fgy.singleton.SingletonPattern06@2e6e1408
解决方法:构造器私有化的时候添加判断句
private SingletonPattern06(){
if(st2!=null){
throw new RuntimeException("防止反射漏洞");
}
}
再重新运行,就ok了
- 通过反序列化漏洞
/**
* 如何防止反射和反序列化漏洞
* @author admin
*
*/
public class CrackSingleton {
public static void main(String[] args) throws Exception{
SingletonPattern06 s=SingletonPattern06.getInstance();
System.out.println(s);
//通过反序列化生成多个对象————>解决方法使用readresolve方法
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("src/反序列化生成多个对象.txt"));
oos.writeObject(s);
oos.close();
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("src/反序列化生成多个对象.txt"));
SingletonPattern06 s3=(SingletonPattern06) ois.readObject();
ois.close();
ObjectInputStream o1=new ObjectInputStream(new FileInputStream("src/反序列化生成多个对象.txt"));
SingletonPattern06 s4=(SingletonPattern06) o1.readObject();
o1.close();
System.out.println(s3);
System.out.println(s4);
com.fgy.singleton.SingletonPattern06@152b6651
com.fgy.singleton.SingletonPattern06@6abf2d5e
com.fgy.singleton.SingletonPattern06@2d3bad12
解决方法:单例模式方法类中添加使用readresolve()方法
private Object readResolve() throws ObjectStreamException{
return st2;
}
再次重新运行,就ok了
完整版的singletonPattern06类如下:
import java.io.ObjectStreamException;
import java.io.Serializable;
/**
* 测试懒汉式(如何防止反射和反序列化)
* @author admin
*
*/
public class SingletonPattern06 implements Serializable{
private static SingletonPattern06 st2;
private SingletonPattern06(){
if(st2!=null){
throw new RuntimeException("防止反射漏洞");
}
}
public static synchronized SingletonPattern06 getInstance(){
if(st2==null){
return st2=new SingletonPattern06();
}
return st2;
}
private Object readResolve() throws ObjectStreamException{
return st2;
}
}
网友评论