从ObjectInputStream读取对象时如何确保安全?

时间:2016-05-23 09:46:27

标签: java security objectinputstream

我尝试了以下实验(这只是一个伪代码):

class Server {
    public static void main(final String args[]) {
        final ServerSocket server = new ServerSocket(PORT);
        final Socket client = server.accept();
        final ObjectInputStream stream = new ObjectInputStream(client.getInputStream());
        final Object object = stream.readObject();
        // Can we hope that standard toString method will be called?
        System.out.println(object.toString());
    }
}

然后创建了一个恶意对象:

class MaliciousObject extends Object implements Serializable {
    private static final long serialVersionUID = 1L;
    @Override
    public String toString() {
        return "I am malicious object";
    }
}

最后使用另一个程序将恶意对象的实例发送到服务器:

public static void main(final String args[]) {
    final Socket socket = new Socket();
    socket.connect(serversAddress, TIMEOUT);
    final ObjectOutputStream stream = new ObjectOutputStream(socket.getOutputStream());
    stream.writeObject(new MaliciousObject());
}

服务器打印到屏幕的输出是

I am malicious object

所以似乎黑客可以实现类扩展对象,覆盖任何方法M来执行某些恶意代码,然后通过网络发送此对象,希望服务器将调用M。

因此,我的问题是:如何防范这个?要是我们 从ObjectInputStream中读取对象,我们怎样才能确定它们没有格式错误?

作为一个附带问题,在这种情况下,从ObjectInputStream读取对象时是否涉及Java类加载器?

2 个答案:

答案 0 :(得分:1)

  

所以似乎黑客可以实现类扩展对象,覆盖任何方法M来执行某些恶意代码,然后通过网络发送此对象,希望服务器将调用M。

没有。该对象不包含代码。该类包含代码,并且该类未被序列化。你已经被“黑客攻击”了。代码,所以在任何序列化之前你已经遇到了问题。

  

我的问题是:如何防范这个?如果我们从ObjectInputStream读取对象,我们怎样才能确保它们不会格式错误?

您不能这样做,但只有在生成所示输出的已编译代码已存在于您的CLASSPATH中时才会出现这种情况,因此您已经遇到问题,序列化或没有序列化。请注意,序列化不会序列化类。

  

作为一个附带问题,在这种情况下,从ObjectInputStream读取对象时是否涉及Java类加载器?

NB Pseudocode不是一个实验,只是一个思想实验。我建议你在现实世界中尝试一下。

答案 1 :(得分:0)