Hi Vipin,
A couple of suggestions to make working with serialization filters easier.
JEP 290 enabled logging of filtering actions by setting
java.io.serialization.level = FINEST.
Add that to the logging.properties and supply it on the command line with
"-Djava.util.logging.config.file=logging.properties".
If set to FINEST, it will log every call to the filter with the
arguments of class, array size, etc.
If set to FINE, it will log only the cases where the filter rejects
based on its arguments.
The pattern based filters can allow or disallow entire packages.
For example, "java.net.**" will allow any class in any package with a
"java.net." prefix.
For development purposes, serialized classes for the registry could be
identified using a filter of "*"
with logging enabled as FINEST and examining the log.
Expanding the white list for the registry is a possibility with a very
conservative
evaluation of specific cases.
Regards, Roger
[1] http://openjdk.java.net/jeps/290
On 1/16/2018 7:21 AM, Vipin Mv1 wrote:
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