Added an example with deserialization filter to UnsafeDeserializationRmi.qhelp

This commit is contained in:
Artem Smotrakov
2021-05-23 13:24:42 +02:00
parent c837605c85
commit 1b51dd47ec
4 changed files with 30 additions and 11 deletions

View File

@@ -0,0 +1,9 @@
public void bindRemoteObject(Registry registry, int port) throws Exception {
ObjectInputFilter filter = info -> {
if (info.serialClass().getCanonicalName().startsWith("com.safe.package.")) {
return ObjectInputFilter.Status.ALLOWED;
}
return ObjectInputFilter.Status.REJECTED;
};
registry.bind("safer", UnicastRemoteObject.exportObject(new RemoteObjectImpl(), port, filter));
}

View File

@@ -1,6 +1,5 @@
public class Server {
public static void main(String... args) throws Exception {
Registry registry = LocateRegistry.createRegistry(1099);
public void bindRemoteObject(Registry registry) throws Exception {
registry.bind("safe", new RemoteObjectImpl());
}
}

View File

@@ -1,6 +1,5 @@
public class Server {
public static void main(String... args) throws Exception {
Registry registry = LocateRegistry.createRegistry(1099);
public void bindRemoteObject(Registry registry) throws Exception {
registry.bind("unsafe", new RemoteObjectImpl());
}
}

View File

@@ -15,14 +15,21 @@ In the worst case, it results in remote code execution.
<p>
Use only strings and primitive types in parameters of remote objects.
</p>
</p>
Set a filter for incoming serialized data by wrapping remote objects using either <code>UnicastRemoteObject.exportObject(Remote, int, ObjectInputFilter)</code>
or <code>UnicastRemoteObject.exportObject(Remote, int, RMIClientSocketFactory, RMIServerSocketFactory, ObjectInputFilter)</code> methods.
Those methods accept an <code>ObjectInputFilter</code> that decides which classes are allowed for deserialization.
The filter should allow deserializing only safe classes.
</p>
<p>
Java RMI does not offer API for specifying classes which are only allowed for deserialization.
However, it is possible to set a process-wide deserialization filter that was introduced in JEP 290.
The filter can be set via system or security property <code>jdk.serialFilter</code>.
It is also possible to set a process-wide deserialization filter.
The filter can be set by with <code>ObjectInputFilter.Config.setSerialFilter(ObjectInputFilter)</code> method,
or by setting system or security property <code>jdk.serialFilter</code>.
Make sure that you use the latest Java versions that include JEP 290.
</p>
<p>
Consider using other implementations of remote procedure calls. For example, HTTP API with JSON.
If switching to the latest Java versions is not possible,
consider using other implementations of remote procedure calls. For example, HTTP API with JSON.
Make sure that the underlying deserialization mechanism is properly configured
so that deserialization attacks are not possible.
</p>
@@ -30,17 +37,22 @@ so that deserialization attacks are not possible.
<example>
<p>
The following code registers a vulnerable remote object
which has a method that accepts a complex object:
The following code registers a remote object
with a vulnerable method that accepts a complex object:
</p>
<sample src="RmiUnsafeRemoteObject.java" />
<p>
The next example registers a safe remote object
which has methods that use only primitive types and strings:
whose methods use only primitive types and strings:
</p>
<sample src="RmiSafeRemoteObject.java" />
<p>
The next example shows how to set a deserilization filter for a remote object:
</p>
<sample src="RmiRemoteObjectWithFilter.java" />
</example>
<references>