Java对象反序列化防护

1  Java对象反序列化之痛

最近一直曝光的开源软件第三方反序列化漏洞:

CVE-2015-7501Commons Collections Java反序列化漏洞

Springframework 反序列化RCE漏洞

都是由于Java对象反序列化本身设计本身缺陷造成的

1.1  Java对象反序列化

Serialization(序列化)是一种将对象以一连串的字节描述的过程;反序列化deserialization是一种将这些字节重建成一个对象的过程。Java API提供一种处理对象序列化和反序列化的标准机制。

1.1.1       序列话/反序列化对象

一个对象能够序列化反序列的前提是实现Serializable,Externalizable接口,Ex:

import java.io.Serializable;

public class test implements Serializable {

    private static final long serialVersionUID = -5809782578272943999L;

    private String name;

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

    }

}

JVM本身提供了ObjectInputStream / ObjectOutputStream序列化反序列化对象

1.1.2       不做校验的反序列化

ObjectInputStream 在做反序列化的时候readSerialData中会通过类反射直接调用序列化对象里的readObject (java.io.ObjectInputStreams) 方法,如果不存在该方法,则将默认调用自身ObjectInputStream的defaultReadObject方法

在整个反序列话过程中,ObjectInputStream只对class是否在自己的classloader中进行了校验,并没有对将要反序列化的对象进行校验。

Ex:

ObjectInputStream ois2= new ObjectInputStream(fis);

test myPerson = (test)ois2.readObject();

 

代码段中通常只是对Object强转成我们想反序列化的对象,通过这种方式来校验传入的序列化对象是否是test, 此时如果构建另一个序列化的对象 test2

import java.io.Serializable;

public class test2 implements Serializable {

    private static final long serialVersionUID = -5809782578272943999L;

    private String name;

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

}

private void readObject(java.io.ObjectInputStream s) {

                     s.defaultReadObject();

                  System.out.println("Hack!");

           }

}

test myPerson = (test)ois2.readObject();

 虽然会报错(类型不匹配),但是关键点是test2中的readObject已经调用了,如果这是一次攻击,在readObject 中已经执行了攻击代码

 

关键点:

1.    在服务器端Class load 能load的class

2.    序列化的对象自己实现了readObject方法

黑客重点关注的能反序列化的对象,常见的开源软件或者JVM自带的支持序列化的类,实现了危险的readObject的方法。

1.1.3       没有足够保护反序列话的java 安全沙箱

Java 本身有一层安全沙箱机制,在反序列化中权限控制只是实现了

1.    enableSubclassImplementation 保护ObjectInputStream, 是否允许使用子类方式,继承和实现自定义的ObjectInputStream

2.    enableSubstitution  是否允许在反序列对象后代替原反序列化对象

2     解决方案

2.1  类白名单校验

在ObjectInputStream 中resolveClass 里只是进行了class 是否能被load,自定义ObjectInputStream, 重载resolveClass的方法,对className 进行白名单校验

public final class SecureObjectInputStream extends ObjectInputStream{

    public SecureObjectInputStream () throws SecurityException, IOException{

        super();

    }

    public SecureObjectInputStream (InputStream inthrows IOException {

        super(in);

    }

   

    protected Class<?> resolveClass(ObjectStreamClass desc)

            throws IOException, ClassNotFoundException{

         if(!desc.getName().equals("test")){  //白名单校验

            throw new ClassNotFoundException(desc.getName()+" not find");

        }

        returnsuper.resolveClass(desc);

    }

}

 

可以通过resolveClass 的方法里实现对class name 进行白名单校验,如果是反序列话的类不在白名单之中的,直接抛出异常。


2.2       Java security安全沙盒进行防护

       如果产品已经使用java 的安全沙盒,建议使用java安全沙箱机制进行防护

1.    设置enableSubclassImplementation

permission java.io.SerializablePermission"enableSubclassImplementation";

2.    自定义ObjectInputStream,重载resolveClass的方法

public final class SecureObjectInputStream extends ObjectInputStream{

    public SecureObjectInputStream() throws SecurityException, IOException{

        super();

    }

    public SecureObjectInputStream(InputStream inthrows IOException {

        super(in);

       

    }

    protected Class<?> resolveClass(ObjectStreamClass desc)

            throws IOException, ClassNotFoundException{

        SecurityManager sm = System.getSecurityManager();

        if (sm != null) {

            sm.checkPermission(

                    new SerializablePermission("accessClass."+desc.getName()));

        }

        return super.resolveClass(desc);

    }

}

 

在policy 文件里设置你的白名单

permission java.io.SerializablePermission "accessClass.test";



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值