Skip to content

Commit 974d915

Browse files
committed
security: implement look-ahead allowlist to block RCE gadgets
1 parent 38be312 commit 974d915

1 file changed

Lines changed: 48 additions & 1 deletion

File tree

caliper-core/src/main/java/com/google/caliper/bridge/OpenedSocket.java

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public static OpenedSocket fromSocket(Socket socket) throws IOException {
4949
// and constructing an ObjectInputStream requires reading that header. So we always need to
5050
// construct the OOS first so we don't deadlock.
5151
ObjectOutputStream output = new ObjectOutputStream(getOutputStream(socket));
52-
ObjectInputStream input = new ObjectInputStream(getInputStream(socket));
52+
ObjectInputStream input = new SafeObjectInputStream(getInputStream(socket));
5353
return new OpenedSocket(new Reader(input), new Writer(output));
5454
}
5555

@@ -96,6 +96,53 @@ public void close() throws IOException {
9696
}
9797
}
9898

99+
private static final class SafeObjectInputStream extends ObjectInputStream {
100+
private static final java.util.Set<String> ALLOWED_CLASSES = java.util.Collections.unmodifiableSet(
101+
new java.util.HashSet<>(java.util.Arrays.asList(
102+
"java.lang.String",
103+
"java.lang.Integer",
104+
"java.lang.Long",
105+
"java.lang.Boolean",
106+
"java.util.ArrayList",
107+
"com.google.caliper.bridge.DryRunSuccessLogMessage",
108+
"com.google.caliper.bridge.ExperimentSpec",
109+
"com.google.caliper.bridge.FailureLogMessage",
110+
"com.google.caliper.bridge.KillVmRequest",
111+
"com.google.caliper.bridge.RemoteClasspathMessage",
112+
"com.google.caliper.bridge.ShouldContinueMessage",
113+
"com.google.caliper.bridge.StartMeasurementLogMessage",
114+
"com.google.caliper.bridge.StartVmRequest",
115+
"com.google.caliper.bridge.StopMeasurementLogMessage",
116+
"com.google.caliper.bridge.StopProxyRequest",
117+
"com.google.caliper.bridge.TargetInfoLogMessage",
118+
"com.google.caliper.bridge.VmPropertiesLogMessage",
119+
"com.google.caliper.bridge.VmStoppedMessage",
120+
"com.google.caliper.bridge.LogMessage",
121+
"com.google.caliper.bridge.StopMessage",
122+
"com.google.caliper.model.Trial",
123+
"com.google.caliper.model.BenchmarkSpec",
124+
"com.google.caliper.model.Host",
125+
"com.google.caliper.model.Run",
126+
"com.google.caliper.model.InstrumentSpec",
127+
"com.google.caliper.bridge.LogMessage",
128+
"com.google.caliper.bridge.StopMessage",
129+
"com.google.caliper.bridge.StartupAnnouncement"
130+
))
131+
);
132+
133+
SafeObjectInputStream(InputStream in) throws IOException {
134+
super(in);
135+
}
136+
137+
@Override
138+
protected Class<?> resolveClass(java.io.ObjectStreamClass desc) throws IOException, ClassNotFoundException {
139+
if (!ALLOWED_CLASSES.contains(desc.getName())) {
140+
throw new java.io.InvalidClassException("Unauthorized deserialization attempt", desc.getName());
141+
}
142+
return super.resolveClass(desc);
143+
}
144+
}
145+
99146
/** Writes objects to the socket. */
100147
public static final class Writer implements Closeable {
101148
private final ObjectOutputStream output;

0 commit comments

Comments
 (0)