From 1b51dd47ec2717f0da468af752134042cbf9abc3 Mon Sep 17 00:00:00 2001
From: Artem Smotrakov
Date: Sun, 23 May 2021 13:24:42 +0200
Subject: [PATCH] Added an example with deserialization filter to
UnsafeDeserializationRmi.qhelp
---
.../CWE-502/RmiRemoteObjectWithFilter.java | 9 +++++++
.../CWE/CWE-502/RmiSafeRemoteObject.java | 3 +--
.../CWE/CWE-502/RmiUnsafeRemoteObject.java | 3 +--
.../CWE-502/UnsafeDeserializationRmi.qhelp | 26 ++++++++++++++-----
4 files changed, 30 insertions(+), 11 deletions(-)
create mode 100644 java/ql/src/experimental/Security/CWE/CWE-502/RmiRemoteObjectWithFilter.java
diff --git a/java/ql/src/experimental/Security/CWE/CWE-502/RmiRemoteObjectWithFilter.java b/java/ql/src/experimental/Security/CWE/CWE-502/RmiRemoteObjectWithFilter.java
new file mode 100644
index 00000000000..6d4d2a5357f
--- /dev/null
+++ b/java/ql/src/experimental/Security/CWE/CWE-502/RmiRemoteObjectWithFilter.java
@@ -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));
+}
diff --git a/java/ql/src/experimental/Security/CWE/CWE-502/RmiSafeRemoteObject.java b/java/ql/src/experimental/Security/CWE/CWE-502/RmiSafeRemoteObject.java
index 2f30bc1f3ba..0c8836522ca 100644
--- a/java/ql/src/experimental/Security/CWE/CWE-502/RmiSafeRemoteObject.java
+++ b/java/ql/src/experimental/Security/CWE/CWE-502/RmiSafeRemoteObject.java
@@ -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());
}
}
diff --git a/java/ql/src/experimental/Security/CWE/CWE-502/RmiUnsafeRemoteObject.java b/java/ql/src/experimental/Security/CWE/CWE-502/RmiUnsafeRemoteObject.java
index 4c04b57cde9..96d48e9c9af 100644
--- a/java/ql/src/experimental/Security/CWE/CWE-502/RmiUnsafeRemoteObject.java
+++ b/java/ql/src/experimental/Security/CWE/CWE-502/RmiUnsafeRemoteObject.java
@@ -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());
}
}
diff --git a/java/ql/src/experimental/Security/CWE/CWE-502/UnsafeDeserializationRmi.qhelp b/java/ql/src/experimental/Security/CWE/CWE-502/UnsafeDeserializationRmi.qhelp
index 1921476ffbd..985e3a4c08d 100644
--- a/java/ql/src/experimental/Security/CWE/CWE-502/UnsafeDeserializationRmi.qhelp
+++ b/java/ql/src/experimental/Security/CWE/CWE-502/UnsafeDeserializationRmi.qhelp
@@ -15,14 +15,21 @@ In the worst case, it results in remote code execution.
Use only strings and primitive types in parameters of remote objects.
+
+Set a filter for incoming serialized data by wrapping remote objects using either UnicastRemoteObject.exportObject(Remote, int, ObjectInputFilter)
+or UnicastRemoteObject.exportObject(Remote, int, RMIClientSocketFactory, RMIServerSocketFactory, ObjectInputFilter) methods.
+Those methods accept an ObjectInputFilter that decides which classes are allowed for deserialization.
+The filter should allow deserializing only safe classes.
+
-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 jdk.serialFilter.
+It is also possible to set a process-wide deserialization filter.
+The filter can be set by with ObjectInputFilter.Config.setSerialFilter(ObjectInputFilter) method,
+or by setting system or security property jdk.serialFilter.
Make sure that you use the latest Java versions that include JEP 290.
-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.
@@ -30,17 +37,22 @@ so that deserialization attacks are not possible.
-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:
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:
+
+The next example shows how to set a deserilization filter for a remote object:
+
+
+