Clarification for adding classes shipped with JDK to sun.rmi.registry.registryFilter property in java.security file
Vipin Mv1
vipinmv1 at in.ibm.com
Tue Jan 16 12:21:38 UTC 2018
Hi,
After upgrading to oracle 8u121-b12, I get following Exception when running
the following testcase.
import java.io.*;
import java.net.InetAddress;
import java.rmi.*;
import java.rmi.registry.*;
import java.security.Security;
/* @test
* @run main/othervm RegistryFilterTest
*/
public class RegistryFilterTest {
private static int port = 12345;
private static Registry registry;
static class RemoteObj implements Serializable, Remote {
private static final long serialVersionUID = 01L;
final Object obj;
RemoteObj(Object obj) {
this.obj = obj;
}
}
public static void main(String[] args) throws Exception{
InetAddress in = InetAddress.getLocalHost();
LocateRegistry.createRegistry(port);
Registry registry = LocateRegistry.getRegistry("localhost",
port);
registry.bind("InetAddress", new RemoteObj(in));
registry.unbind("InetAddress");
System.out.println("RMI Registry Test Passed");
}
}
TestResults
-----------------------
Jan 12, 2018 5:32:18 PM java.io.ObjectInputStream filterCheck
INFO: ObjectInputFilter REJECTED: class java.net.InetAddress, array length:
-1, nRefs: 5, depth: 2, bytes: 216, ex: n/a
Caused by: java.io.InvalidClassException: filter status: REJECTED
at java.io.ObjectInputStream.filterCheck(ObjectInputStream.java:1406)
at java.io.ObjectInputStream.readNonProxyDesc
(ObjectInputStream.java:1997)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1877)
at java.io.ObjectInputStream.readOrdinaryObject
(ObjectInputStream.java:2170)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1698)
at java.io.ObjectInputStream.defaultReadFields
(ObjectInputStream.java:2415)
at java.io.ObjectInputStream.readSerialData
(ObjectInputStream.java:2339)
at java.io.ObjectInputStream.readOrdinaryObject
(ObjectInputStream.java:2197)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1698)
at java.io.ObjectInputStream.readObjectImpl(ObjectInputStream.java:540)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:475)
... 16 more
I understand it is due to the new serialization Filtering mechanism
introduced to RMI Registry and Distributed Garbage Collection as a part of
the following fixes.
JDK-8160108 Implement Serialization Filtering
JDK-8156804: Better constraint checking(not public)
As a result, a new default white list has been introduced for RMIRegistry
which allows deserialization only to limited set of classes by default.
Which are
String.class
java.lang.Number.class
java.rmi.Remote.class
java.lang.reflect.Proxy.class
sun.rmi.server.UnicastRef.class
java.rmi.server.RMIClientSocketFactory.class
java.rmi.server.RMIServerSocketFactory.class
java.rmi.activation.ActivationID.class
java.rmi.server.UID.class
and their subclasses.
It also enabled provisions to increase the default white list by
1. updating property "sun.rmi.registry.registryFilter" in java.security
file
2. adding -Dsun.rmi.registry.registryFilter in java command line
Though the current solution is straight forward, it is difficult from an
application point of view to identify such classes without running the
application multiple times to come up with comprehensive list to be
allowed. This would be a overhead to the developer and should be avoided at
least for classes shipped with JDK (for example, java.net.InetAddress as
used in testcase).
I assume that default list is very limited to reduce the chances of getting
exploited by serialization vulnerability. I think, we can spare public
packages shipped with JDK by adding them to
"sun.rmi.registry.registryFilter" in java.security file out of the box.
Please let me know your views.
Thanks & Regards,
Vipin MV
More information about the core-libs-dev
mailing list