Skip to content

Commit ce3b0e2

Browse files
authored
Add serializable check for pojo (#11431)
1 parent 5c895d4 commit ce3b0e2

File tree

9 files changed

+92
-51
lines changed

9 files changed

+92
-51
lines changed

dubbo-common/src/main/java/org/apache/dubbo/common/beanutil/JavaBeanSerializeUtil.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,6 @@
1616
*/
1717
package org.apache.dubbo.common.beanutil;
1818

19-
import org.apache.dubbo.common.logger.Logger;
20-
import org.apache.dubbo.common.logger.LoggerFactory;
21-
import org.apache.dubbo.common.utils.LogHelper;
22-
import org.apache.dubbo.common.utils.ReflectUtils;
23-
import org.apache.dubbo.common.utils.SerializeClassChecker;
24-
2519
import java.lang.reflect.Array;
2620
import java.lang.reflect.Constructor;
2721
import java.lang.reflect.Field;
@@ -32,6 +26,12 @@
3226
import java.util.IdentityHashMap;
3327
import java.util.Map;
3428

29+
import org.apache.dubbo.common.logger.Logger;
30+
import org.apache.dubbo.common.logger.LoggerFactory;
31+
import org.apache.dubbo.common.utils.LogHelper;
32+
import org.apache.dubbo.common.utils.ReflectUtils;
33+
import org.apache.dubbo.common.utils.SerializeClassChecker;
34+
3535
public final class JavaBeanSerializeUtil {
3636

3737
private static final Logger logger = LoggerFactory.getLogger(JavaBeanSerializeUtil.class);
@@ -466,7 +466,9 @@ public static Class<?> name2Class(ClassLoader loader, String name) throws ClassN
466466
name = name.substring(1, name.length() - 1);
467467
}
468468
SerializeClassChecker.getInstance().validateClass(name);
469-
return Class.forName(name, false, loader);
469+
Class<?> aClass = Class.forName(name, false, loader);
470+
SerializeClassChecker.getInstance().validateClass(aClass);
471+
return aClass;
470472
}
471473

472474
private static boolean isArray(String type) {

dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@
1717

1818
package org.apache.dubbo.common.constants;
1919

20-
import org.apache.dubbo.common.URL;
21-
2220
import java.net.NetworkInterface;
2321
import java.util.Properties;
2422
import java.util.concurrent.ExecutorService;
2523
import java.util.regex.Pattern;
2624

25+
import org.apache.dubbo.common.URL;
26+
2727
public interface CommonConstants {
2828
String DUBBO = "dubbo";
2929

@@ -412,6 +412,8 @@ public interface CommonConstants {
412412

413413
String CLASS_DESERIALIZE_BLOCKED_LIST = "dubbo.security.serialize.blockedClassList";
414414

415+
String CLASS_DESERIALIZE_CHECK_SERIALIZABLE = "dubbo.application.check-serializable";
416+
415417
String ENABLE_NATIVE_JAVA_GENERIC_SERIALIZE = "dubbo.security.serialize.generic.native-java-enable";
416418

417419
String SERIALIZE_BLOCKED_LIST_FILE_PATH = "security/serialize.blockedlist";

dubbo-common/src/main/java/org/apache/dubbo/common/utils/PojoUtils.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,6 @@
1616
*/
1717
package org.apache.dubbo.common.utils;
1818

19-
import org.apache.dubbo.common.config.ConfigurationUtils;
20-
import org.apache.dubbo.common.constants.CommonConstants;
21-
import org.apache.dubbo.common.logger.Logger;
22-
import org.apache.dubbo.common.logger.LoggerFactory;
23-
2419
import java.lang.reflect.Array;
2520
import java.lang.reflect.Constructor;
2621
import java.lang.reflect.Field;
@@ -55,6 +50,11 @@
5550
import java.util.function.Consumer;
5651
import java.util.function.Supplier;
5752

53+
import org.apache.dubbo.common.config.ConfigurationUtils;
54+
import org.apache.dubbo.common.constants.CommonConstants;
55+
import org.apache.dubbo.common.logger.Logger;
56+
import org.apache.dubbo.common.logger.LoggerFactory;
57+
5858
import static org.apache.dubbo.common.utils.ClassUtils.isAssignableFrom;
5959

6060
/**
@@ -410,6 +410,7 @@ private static Object realize0(Object pojo, Class<?> type, Type genericType, fin
410410
CLASS_NOT_FOUND_CACHE.put((String) className, NOT_FOUND_VALUE);
411411
}
412412
}
413+
SerializeClassChecker.getInstance().validateClass(type);
413414
}
414415

415416
// special logic for enum

dubbo-common/src/main/java/org/apache/dubbo/common/utils/SerializeClassChecker.java

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,19 @@
1616
*/
1717
package org.apache.dubbo.common.utils;
1818

19-
import org.apache.dubbo.common.beanutil.JavaBeanSerializeUtil;
20-
import org.apache.dubbo.common.logger.Logger;
21-
import org.apache.dubbo.common.logger.LoggerFactory;
22-
2319
import java.io.IOException;
20+
import java.io.Serializable;
2421
import java.util.Arrays;
2522
import java.util.Locale;
2623
import java.util.Set;
2724
import java.util.concurrent.atomic.AtomicLong;
2825

26+
import org.apache.dubbo.common.beanutil.JavaBeanSerializeUtil;
27+
import org.apache.dubbo.common.config.ConfigurationUtils;
28+
import org.apache.dubbo.common.constants.CommonConstants;
29+
import org.apache.dubbo.common.logger.Logger;
30+
import org.apache.dubbo.common.logger.LoggerFactory;
31+
2932
import static org.apache.dubbo.common.constants.CommonConstants.CLASS_DESERIALIZE_ALLOWED_LIST;
3033
import static org.apache.dubbo.common.constants.CommonConstants.CLASS_DESERIALIZE_BLOCKED_LIST;
3134
import static org.apache.dubbo.common.constants.CommonConstants.CLASS_DESERIALIZE_BLOCK_ALL;
@@ -44,6 +47,8 @@ public class SerializeClassChecker {
4447
private final LFUCache<String, Object> CLASS_ALLOW_LFU_CACHE = new LFUCache<>();
4548
private final LFUCache<String, Object> CLASS_BLOCK_LFU_CACHE = new LFUCache<>();
4649

50+
private final boolean checkSerializable;
51+
4752
private final AtomicLong counter = new AtomicLong(0);
4853

4954
private SerializeClassChecker() {
@@ -83,6 +88,7 @@ private SerializeClassChecker() {
8388
CLASS_DESERIALIZE_BLOCKED_SET.addAll(Arrays.asList(classStrings));
8489
}
8590

91+
checkSerializable = Boolean.parseBoolean(ConfigurationUtils.getProperty(CommonConstants.CLASS_DESERIALIZE_CHECK_SERIALIZABLE, "true"));
8692
}
8793

8894
public static SerializeClassChecker getInstance() {
@@ -137,6 +143,12 @@ public void validateClass(String name) {
137143
CLASS_ALLOW_LFU_CACHE.put(name, CACHE);
138144
}
139145

146+
public void validateClass(Class<?> aClass) {
147+
if (checkSerializable && !Serializable.class.isAssignableFrom(aClass)) {
148+
error(aClass.getName());
149+
}
150+
}
151+
140152
private void error(String name) {
141153
String notice = "Trigger the safety barrier! " +
142154
"Catch not allowed serialize class. " +

dubbo-common/src/test/java/org/apache/dubbo/common/beanutil/Bean.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
package org.apache.dubbo.common.beanutil;
22

3-
import org.apache.dubbo.rpc.model.person.FullAddress;
4-
import org.apache.dubbo.rpc.model.person.PersonStatus;
5-
import org.apache.dubbo.rpc.model.person.Phone;
6-
3+
import java.io.Serializable;
74
import java.util.Collection;
85
import java.util.Date;
96
import java.util.Map;
7+
8+
import org.apache.dubbo.rpc.model.person.FullAddress;
9+
import org.apache.dubbo.rpc.model.person.PersonStatus;
10+
import org.apache.dubbo.rpc.model.person.Phone;
1011
/*
1112
* Licensed to the Apache Software Foundation (ASF) under one or more
1213
* contributor license agreements. See the NOTICE file distributed with
@@ -23,7 +24,7 @@
2324
* See the License for the specific language governing permissions and
2425
* limitations under the License.
2526
*/
26-
public class Bean {
27+
public class Bean implements Serializable {
2728

2829
private Class<?> type;
2930

dubbo-common/src/test/java/org/apache/dubbo/common/model/Person.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@
1616
*/
1717
package org.apache.dubbo.common.model;
1818

19+
import java.io.Serializable;
1920
import java.util.Arrays;
2021

21-
public class Person {
22+
public class Person implements Serializable {
2223
byte oneByte = 123;
2324
private String name = "name1";
2425
private int age = 11;

dubbo-common/src/test/java/org/apache/dubbo/common/model/User.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,13 @@
1717

1818
package org.apache.dubbo.common.model;
1919

20+
import java.io.Serializable;
2021
import java.util.Objects;
2122

2223
/**
2324
* this class has no nullary constructor and some field is primitive
2425
*/
25-
public class User {
26+
public class User implements Serializable {
2627
private int age;
2728

2829
private String name;

dubbo-common/src/test/java/org/apache/dubbo/common/utils/PojoUtilsTest.java

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,7 @@
1616
*/
1717
package org.apache.dubbo.common.utils;
1818

19-
import org.apache.dubbo.common.model.Person;
20-
import org.apache.dubbo.common.model.SerializablePerson;
21-
import org.apache.dubbo.common.model.User;
22-
import org.apache.dubbo.common.model.person.BigPerson;
23-
import org.apache.dubbo.common.model.person.FullAddress;
24-
import org.apache.dubbo.common.model.person.PersonInfo;
25-
import org.apache.dubbo.common.model.person.PersonStatus;
26-
import org.apache.dubbo.common.model.person.Phone;
27-
28-
import com.alibaba.fastjson.JSONObject;
29-
import org.junit.jupiter.api.Assertions;
30-
import org.junit.jupiter.api.Test;
31-
19+
import java.io.Serializable;
3220
import java.lang.reflect.Method;
3321
import java.lang.reflect.Type;
3422
import java.text.SimpleDateFormat;
@@ -43,6 +31,19 @@
4331
import java.util.Map;
4432
import java.util.UUID;
4533

34+
import org.apache.dubbo.common.model.Person;
35+
import org.apache.dubbo.common.model.SerializablePerson;
36+
import org.apache.dubbo.common.model.User;
37+
import org.apache.dubbo.common.model.person.BigPerson;
38+
import org.apache.dubbo.common.model.person.FullAddress;
39+
import org.apache.dubbo.common.model.person.PersonInfo;
40+
import org.apache.dubbo.common.model.person.PersonStatus;
41+
import org.apache.dubbo.common.model.person.Phone;
42+
import org.junit.jupiter.api.Assertions;
43+
import org.junit.jupiter.api.Test;
44+
45+
import com.alibaba.fastjson.JSONObject;
46+
4647
import static org.hamcrest.MatcherAssert.assertThat;
4748
import static org.hamcrest.Matchers.equalTo;
4849
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
@@ -764,7 +765,7 @@ public enum Day {
764765
SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
765766
}
766767

767-
public static class BasicTestData {
768+
public static class BasicTestData implements Serializable {
768769

769770
public boolean a;
770771
public char b;
@@ -836,7 +837,7 @@ public boolean equals(Object obj) {
836837

837838
}
838839

839-
public static class Parent {
840+
public static class Parent implements Serializable {
840841
public String gender;
841842
public String email;
842843
String name;
@@ -881,7 +882,7 @@ public void setChild(Child child) {
881882
}
882883
}
883884

884-
public static class Child {
885+
public static class Child implements Serializable {
885886
public String gender;
886887
public int age;
887888
String toy;
@@ -921,7 +922,7 @@ public void setParent(Parent parent) {
921922
}
922923
}
923924

924-
public static class TestData {
925+
public static class TestData implements Serializable {
925926
private Map<String, Child> children = new HashMap<String, Child>();
926927
private List<Child> list = new ArrayList<Child>();
927928

@@ -950,7 +951,7 @@ public void addChild(Child child) {
950951
}
951952
}
952953

953-
public static class InnerPojo<T> {
954+
public static class InnerPojo<T> implements Serializable {
954955
private List<T> list;
955956

956957
public List<T> getList() {
@@ -962,7 +963,7 @@ public void setList(List<T> list) {
962963
}
963964
}
964965

965-
public static class ListResult<T> {
966+
public static class ListResult<T> implements Serializable {
966967
List<T> result;
967968

968969
public List<T> getResult() {

dubbo-common/src/test/java/org/apache/dubbo/common/utils/SerializeClassCheckerTest.java

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,18 @@
1616
*/
1717
package org.apache.dubbo.common.utils;
1818

19-
import org.apache.dubbo.common.constants.CommonConstants;
19+
import java.net.Socket;
20+
import java.util.LinkedList;
21+
import java.util.List;
22+
import java.util.Locale;
2023

21-
import javassist.compiler.Javac;
24+
import org.apache.dubbo.common.constants.CommonConstants;
25+
import org.junit.jupiter.api.AfterAll;
2226
import org.junit.jupiter.api.Assertions;
2327
import org.junit.jupiter.api.BeforeEach;
24-
import org.junit.jupiter.api.AfterAll;
2528
import org.junit.jupiter.api.Test;
2629

27-
import java.net.Socket;
28-
import java.util.LinkedList;
29-
import java.util.List;
30-
import java.util.Locale;
30+
import javassist.compiler.Javac;
3131

3232
public class SerializeClassCheckerTest {
3333

@@ -62,6 +62,26 @@ public void testCommon() {
6262
});
6363
}
6464

65+
@Test
66+
public void testSerializable1() {
67+
SerializeClassChecker serializeClassChecker = SerializeClassChecker.getInstance();
68+
Assertions.assertThrows(IllegalArgumentException.class, ()-> serializeClassChecker.validateClass(List.class));
69+
}
70+
71+
@Test
72+
public void testSerializable2() {
73+
System.setProperty(CommonConstants.CLASS_DESERIALIZE_CHECK_SERIALIZABLE, "false");
74+
SerializeClassChecker serializeClassChecker = SerializeClassChecker.getInstance();
75+
76+
try {
77+
serializeClassChecker.validateClass(List.class);
78+
} catch (Throwable t) {
79+
Assertions.fail(t);
80+
}
81+
82+
System.clearProperty(CommonConstants.CLASS_DESERIALIZE_CHECK_SERIALIZABLE);
83+
}
84+
6585
@Test
6686
public void testAddAllow() {
6787
System.setProperty(CommonConstants.CLASS_DESERIALIZE_ALLOWED_LIST, Socket.class.getName() + "," + Javac.class.getName());

0 commit comments

Comments
 (0)