Skip to content

Commit ecba29d

Browse files
authored
Merge pull request #1308 from harawata/deserialization-vuln
Prevent known vulnerable classes from being deserialized.
2 parents 67a1c4e + 61488d4 commit ecba29d

File tree

1 file changed

+32
-2
lines changed

1 file changed

+32
-2
lines changed

src/main/java/org/apache/ibatis/executor/loader/AbstractSerialStateHolder.java

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,13 @@
1919
import java.io.ByteArrayOutputStream;
2020
import java.io.Externalizable;
2121
import java.io.IOException;
22+
import java.io.InputStream;
2223
import java.io.InvalidClassException;
2324
import java.io.ObjectInput;
2425
import java.io.ObjectInputStream;
2526
import java.io.ObjectOutput;
2627
import java.io.ObjectOutputStream;
28+
import java.io.ObjectStreamClass;
2729
import java.io.ObjectStreamException;
2830
import java.io.StreamCorruptedException;
2931
import java.util.Arrays;
@@ -107,8 +109,7 @@ protected final Object readResolve() throws ObjectStreamException {
107109
}
108110

109111
/* First run */
110-
try {
111-
final ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(this.userBeanBytes));
112+
try (final ObjectInputStream in = new LookAheadObjectInputStream(new ByteArrayInputStream(this.userBeanBytes))) {
112113
this.userBean = in.readObject();
113114
this.unloadedProperties = (Map<String, ResultLoaderMap.LoadPair>) in.readObject();
114115
this.objectFactory = (ObjectFactory) in.readObject();
@@ -129,4 +130,33 @@ protected final Object readResolve() throws ObjectStreamException {
129130

130131
protected abstract Object createDeserializationProxy(Object target, Map<String, ResultLoaderMap.LoadPair> unloadedProperties, ObjectFactory objectFactory,
131132
List<Class<?>> constructorArgTypes, List<Object> constructorArgs);
133+
134+
private static class LookAheadObjectInputStream extends ObjectInputStream {
135+
private static final List<String> blacklist = Arrays.asList(
136+
"org.apache.commons.beanutils.BeanComparator",
137+
"org.apache.commons.collections.functors.InvokerTransformer",
138+
"org.apache.commons.collections.functors.InstantiateTransformer",
139+
"org.apache.commons.collections4.functors.InvokerTransformer",
140+
"org.apache.commons.collections4.functors.InstantiateTransformer",
141+
"org.codehaus.groovy.runtime.ConvertedClosure",
142+
"org.codehaus.groovy.runtime.MethodClosure",
143+
"org.springframework.beans.factory.ObjectFactory",
144+
"org.springframework.transaction.jta.JtaTransactionManager",
145+
"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl");
146+
147+
public LookAheadObjectInputStream(InputStream in) throws IOException {
148+
super(in);
149+
}
150+
151+
@Override
152+
protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
153+
String className = desc.getName();
154+
if (blacklist.contains(className)) {
155+
throw new InvalidClassException(className, "Deserialization is not allowed for security reasons. "
156+
+ "It is strongly recommended to configure the deserialization filter provided by JDK. "
157+
+ "See http://openjdk.java.net/jeps/290 for the details.");
158+
}
159+
return super.resolveClass(desc);
160+
}
161+
}
132162
}

0 commit comments

Comments
 (0)