Skip to content

Commit d89b300

Browse files
authored
Merge pull request #2079 from harawata/desrialization-warning
Output warning when deserializing object stream
2 parents 6c6756c + 9caf480 commit d89b300

File tree

3 files changed

+61
-33
lines changed

3 files changed

+61
-33
lines changed

src/main/java/org/apache/ibatis/cache/decorators/SerializedCache.java

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.apache.ibatis.cache.Cache;
2828
import org.apache.ibatis.cache.CacheException;
2929
import org.apache.ibatis.io.Resources;
30+
import org.apache.ibatis.io.SerialFilterChecker;
3031

3132
/**
3233
* @author Clinton Begin
@@ -96,6 +97,7 @@ private byte[] serialize(Serializable value) {
9697
}
9798

9899
private Serializable deserialize(byte[] value) {
100+
SerialFilterChecker.check();
99101
Serializable result;
100102
try (ByteArrayInputStream bis = new ByteArrayInputStream(value);
101103
ObjectInputStream ois = new CustomObjectInputStream(bis)) {

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

+5-33
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2009-2019 the original author or authors.
2+
* Copyright 2009-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -19,20 +19,19 @@
1919
import java.io.ByteArrayOutputStream;
2020
import java.io.Externalizable;
2121
import java.io.IOException;
22-
import java.io.InputStream;
2322
import java.io.InvalidClassException;
2423
import java.io.ObjectInput;
2524
import java.io.ObjectInputStream;
2625
import java.io.ObjectOutput;
2726
import java.io.ObjectOutputStream;
28-
import java.io.ObjectStreamClass;
2927
import java.io.ObjectStreamException;
3028
import java.io.StreamCorruptedException;
3129
import java.util.Arrays;
3230
import java.util.HashMap;
3331
import java.util.List;
3432
import java.util.Map;
3533

34+
import org.apache.ibatis.io.SerialFilterChecker;
3635
import org.apache.ibatis.reflection.factory.ObjectFactory;
3736

3837
/**
@@ -108,8 +107,10 @@ protected final Object readResolve() throws ObjectStreamException {
108107
return this.userBean;
109108
}
110109

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

131132
protected abstract Object createDeserializationProxy(Object target, Map<String, ResultLoaderMap.LoadPair> unloadedProperties, ObjectFactory objectFactory,
132133
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-
}
162134
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/**
2+
* Copyright 2009-2020 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.apache.ibatis.io;
18+
19+
import java.security.Security;
20+
21+
import org.apache.ibatis.logging.Log;
22+
import org.apache.ibatis.logging.LogFactory;
23+
24+
public final class SerialFilterChecker {
25+
private static final Log log = LogFactory.getLog(SerialFilterChecker.class);
26+
/* Property key for the JEP-290 serialization filters */
27+
private static final String JDK_SERIAL_FILTER = "jdk.serialFilter";
28+
private static final boolean SERIAL_FILTER_MISSING;
29+
private static boolean firstInvocation = true;
30+
31+
static {
32+
Object serialFilter;
33+
try {
34+
Class<?> objectFilterConfig = Class.forName("java.io.ObjectInputFilter$Config");
35+
serialFilter = objectFilterConfig.getMethod("getSerialFilter").invoke(null);
36+
} catch (ReflectiveOperationException e) {
37+
// Java 1.8
38+
serialFilter = System.getProperty(JDK_SERIAL_FILTER, Security.getProperty(JDK_SERIAL_FILTER));
39+
}
40+
SERIAL_FILTER_MISSING = serialFilter == null;
41+
}
42+
43+
public static void check() {
44+
if (firstInvocation && SERIAL_FILTER_MISSING) {
45+
firstInvocation = false;
46+
log.warn(
47+
"As you are using functionality that deserializes object streams, it is recommended to define the JEP-290 serial filter. "
48+
+ "Please refer to https://docs.oracle.com/pls/topic/lookup?ctx=javase15&id=GUID-8296D8E8-2B93-4B9A-856E-0A65AF9B8C66");
49+
}
50+
}
51+
52+
private SerialFilterChecker() {
53+
}
54+
}

0 commit comments

Comments
 (0)