From 436d674aa020046140b4bdb0361ec58141e60fc6 Mon Sep 17 00:00:00 2001 From: jimin Date: Mon, 28 Aug 2023 12:02:28 +0800 Subject: [PATCH] security: fix some serializer vulnerabilities (#5805) --- changes/en-us/2.0.0.md | 1 + changes/zh-cn/2.0.0.md | 1 + .../io/seata/core/protocol/MergeMessage.java | 4 +- .../io/seata/core/protocol/RpcMessage.java | 3 +- .../serializer/SerializerClassRegistry.java | 157 ---------------- .../SerializerSecurityRegistry.java | 168 ++++++++++++++++++ .../SerializerSecurityRegistryTest.java | 60 +++++++ .../serializer/fst/FstSerializerFactory.java | 4 +- .../hessian/HessianSerializerFactory.java | 71 ++------ .../kryo/KryoSerializerFactory.java | 32 +--- server/src/main/resources/application.yml | 4 +- 11 files changed, 258 insertions(+), 247 deletions(-) delete mode 100644 core/src/main/java/io/seata/core/serializer/SerializerClassRegistry.java create mode 100644 core/src/main/java/io/seata/core/serializer/SerializerSecurityRegistry.java create mode 100644 core/src/test/java/io/seata/core/serializer/SerializerSecurityRegistryTest.java diff --git a/changes/en-us/2.0.0.md b/changes/en-us/2.0.0.md index b48c4f239a3..fd527e5617e 100644 --- a/changes/en-us/2.0.0.md +++ b/changes/en-us/2.0.0.md @@ -115,6 +115,7 @@ The version is updated as follows: - [[#5642](https://github.com/seata/seata/pull/5642)] add Hessian Serializer WhiteDenyList - [[#5694](https://github.com/seata/seata/pull/5694)] fix several node.js security vulnerabilities - [[#5801](https://github.com/seata/seata/pull/5801)] fix some dependencies vulnerability +- [[#5805](https://github.com/seata/seata/pull/5805)] fix some serializer vulnerabilities ### test: - [[#5308](https://github.com/seata/seata/pull/5308)] add unit test [FileLoader, ObjectHolder, StringUtils] diff --git a/changes/zh-cn/2.0.0.md b/changes/zh-cn/2.0.0.md index 3cb73ef0321..82cbfe7df11 100644 --- a/changes/zh-cn/2.0.0.md +++ b/changes/zh-cn/2.0.0.md @@ -115,6 +115,7 @@ Seata 是一款开源的分布式事务解决方案,提供高性能和简单 - [[#5642](https://github.com/seata/seata/pull/5642)] 增加Hessian 序列化黑白名单 - [[#5694](https://github.com/seata/seata/pull/5694)] 修复若干Node.js依赖安全漏洞 - [[#5801](https://github.com/seata/seata/pull/5801)] 修复Java依赖安全漏洞 +- [[#5805](https://github.com/seata/seata/pull/5805)] 修复序列化漏洞 ### test: - [[#5308](https://github.com/seata/seata/pull/5308)] 添加单元测试用例 [FileLoader, ObjectHolder, StringUtils] diff --git a/core/src/main/java/io/seata/core/protocol/MergeMessage.java b/core/src/main/java/io/seata/core/protocol/MergeMessage.java index f54db37a85d..82b2a678bb3 100644 --- a/core/src/main/java/io/seata/core/protocol/MergeMessage.java +++ b/core/src/main/java/io/seata/core/protocol/MergeMessage.java @@ -15,10 +15,12 @@ */ package io.seata.core.protocol; +import java.io.Serializable; + /** * The interface Merge message. * * @author slievrly */ -public interface MergeMessage { +public interface MergeMessage extends Serializable { } diff --git a/core/src/main/java/io/seata/core/protocol/RpcMessage.java b/core/src/main/java/io/seata/core/protocol/RpcMessage.java index 02d611ce242..fe229b3662b 100644 --- a/core/src/main/java/io/seata/core/protocol/RpcMessage.java +++ b/core/src/main/java/io/seata/core/protocol/RpcMessage.java @@ -17,6 +17,7 @@ import io.seata.common.util.StringUtils; +import java.io.Serializable; import java.util.HashMap; import java.util.Map; @@ -25,7 +26,7 @@ * * @author slievrly */ -public class RpcMessage { +public class RpcMessage implements Serializable { private int id; private byte messageType; diff --git a/core/src/main/java/io/seata/core/serializer/SerializerClassRegistry.java b/core/src/main/java/io/seata/core/serializer/SerializerClassRegistry.java deleted file mode 100644 index 6ffe71cd36a..00000000000 --- a/core/src/main/java/io/seata/core/serializer/SerializerClassRegistry.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright 1999-2019 Seata.io Group. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.seata.core.serializer; - -import java.util.ArrayList; -import java.util.BitSet; -import java.util.Calendar; -import java.util.Date; -import java.util.GregorianCalendar; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Hashtable; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.Map; -import java.util.TreeSet; -import java.util.Vector; -import java.util.concurrent.ConcurrentHashMap; - -import io.seata.core.protocol.MergeResultMessage; -import io.seata.core.protocol.MergedWarpMessage; -import io.seata.core.protocol.RegisterRMRequest; -import io.seata.core.protocol.RegisterRMResponse; -import io.seata.core.protocol.RegisterTMRequest; -import io.seata.core.protocol.RegisterTMResponse; -import io.seata.core.protocol.transaction.BranchCommitRequest; -import io.seata.core.protocol.transaction.BranchCommitResponse; -import io.seata.core.protocol.transaction.BranchRegisterRequest; -import io.seata.core.protocol.transaction.BranchRegisterResponse; -import io.seata.core.protocol.transaction.BranchReportRequest; -import io.seata.core.protocol.transaction.BranchReportResponse; -import io.seata.core.protocol.transaction.BranchRollbackRequest; -import io.seata.core.protocol.transaction.BranchRollbackResponse; -import io.seata.core.protocol.transaction.GlobalBeginRequest; -import io.seata.core.protocol.transaction.GlobalBeginResponse; -import io.seata.core.protocol.transaction.GlobalCommitRequest; -import io.seata.core.protocol.transaction.GlobalCommitResponse; -import io.seata.core.protocol.transaction.GlobalLockQueryRequest; -import io.seata.core.protocol.transaction.GlobalLockQueryResponse; -import io.seata.core.protocol.transaction.GlobalReportRequest; -import io.seata.core.protocol.transaction.GlobalReportResponse; -import io.seata.core.protocol.transaction.GlobalRollbackRequest; -import io.seata.core.protocol.transaction.GlobalRollbackResponse; -import io.seata.core.protocol.transaction.GlobalStatusRequest; -import io.seata.core.protocol.transaction.GlobalStatusResponse; -import io.seata.core.protocol.transaction.UndoLogDeleteRequest; - -/** - * Provide a unified serialization registry, this class used for {@code seata-serializer-fst} - * and {@code seata-serializer-kryo}, it will register some classes at startup time (for example {@code KryoSerializerFactory#create}) - * @author funkye - */ -public class SerializerClassRegistry { - - private static final Map, Object> REGISTRATIONS = new LinkedHashMap<>(); - - static { - - // register commonly class - registerClass(HashMap.class); - registerClass(ArrayList.class); - registerClass(LinkedList.class); - registerClass(HashSet.class); - registerClass(TreeSet.class); - registerClass(Hashtable.class); - registerClass(Date.class); - registerClass(Calendar.class); - registerClass(ConcurrentHashMap.class); - registerClass(GregorianCalendar.class); - registerClass(Vector.class); - registerClass(BitSet.class); - registerClass(StringBuffer.class); - registerClass(StringBuilder.class); - registerClass(Object.class); - registerClass(Object[].class); - registerClass(String[].class); - registerClass(byte[].class); - registerClass(char[].class); - registerClass(int[].class); - registerClass(float[].class); - registerClass(double[].class); - - // register seata protocol relation class - registerClass(BranchCommitRequest.class); - registerClass(BranchCommitResponse.class); - registerClass(BranchRegisterRequest.class); - registerClass(BranchRegisterResponse.class); - registerClass(BranchReportRequest.class); - registerClass(BranchReportResponse.class); - registerClass(BranchRollbackRequest.class); - registerClass(BranchRollbackResponse.class); - registerClass(GlobalBeginRequest.class); - registerClass(GlobalBeginResponse.class); - registerClass(GlobalCommitRequest.class); - registerClass(GlobalCommitResponse.class); - registerClass(GlobalLockQueryRequest.class); - registerClass(GlobalLockQueryResponse.class); - registerClass(GlobalRollbackRequest.class); - registerClass(GlobalRollbackResponse.class); - registerClass(GlobalStatusRequest.class); - registerClass(GlobalStatusResponse.class); - registerClass(UndoLogDeleteRequest.class); - registerClass(GlobalReportRequest.class); - registerClass(GlobalReportResponse.class); - - registerClass(MergedWarpMessage.class); - registerClass(MergeResultMessage.class); - registerClass(RegisterRMRequest.class); - registerClass(RegisterRMResponse.class); - registerClass(RegisterTMRequest.class); - registerClass(RegisterTMResponse.class); - } - - /** - * only supposed to be called at startup time - * - * @param clazz object type - */ - public static void registerClass(Class clazz) { - registerClass(clazz, null); - } - - /** - * only supposed to be called at startup time - * - * @param clazz object type - * @param serializer object serializer - */ - public static void registerClass(Class clazz, Object serializer) { - if (clazz == null) { - throw new IllegalArgumentException("Class registered cannot be null!"); - } - REGISTRATIONS.put(clazz, serializer); - } - - /** - * get registered classes - * - * @return class serializer - * */ - public static Map, Object> getRegisteredClasses() { - return REGISTRATIONS; - } -} diff --git a/core/src/main/java/io/seata/core/serializer/SerializerSecurityRegistry.java b/core/src/main/java/io/seata/core/serializer/SerializerSecurityRegistry.java new file mode 100644 index 00000000000..1d4b65e4fd1 --- /dev/null +++ b/core/src/main/java/io/seata/core/serializer/SerializerSecurityRegistry.java @@ -0,0 +1,168 @@ +/* + * Copyright 1999-2019 Seata.io Group. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.seata.core.serializer; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; + +import io.seata.core.exception.TransactionExceptionCode; +import io.seata.core.model.BranchStatus; +import io.seata.core.model.BranchType; +import io.seata.core.model.GlobalStatus; +import io.seata.core.protocol.ResultCode; + +/** + * Serializer Security Registry + * @author funkye + */ +public class SerializerSecurityRegistry { + private static final Set> ALLOW_CLAZZ_SET = new HashSet<>(); + + private static final Set ALLOW_CLAZZ_PATTERN = new HashSet<>(); + + private static final Set DENY_CLAZZ_PATTERN = new HashSet<>(); + + private static final String CLASS_POSTFIX = ".class"; + + private static final String ABSTRACT_CLASS_ID = "Abstract"; + + private static final String REQUEST_CLASS_ID = "Request"; + + private static final String RESPONSE_CLASS_ID = "Response"; + + private static final String MESSAGE_CLASS_ID = "Message"; + + static { + ALLOW_CLAZZ_SET.addAll(Arrays.asList(getBasicClassType())); + ALLOW_CLAZZ_SET.addAll(Arrays.asList(getCollectionClassType())); + ALLOW_CLAZZ_SET.addAll(getProtocolType()); + ALLOW_CLAZZ_SET.addAll(Arrays.asList(getProtocolInnerFields())); + + for (Class clazz : ALLOW_CLAZZ_SET) { + ALLOW_CLAZZ_PATTERN.add(clazz.getCanonicalName()); + } + ALLOW_CLAZZ_PATTERN.add(getSeataClassPattern()); + + DENY_CLAZZ_PATTERN.addAll(Arrays.asList(getDenyClassPatternList())); + } + + public static Set> getAllowClassType() { + return Collections.unmodifiableSet(ALLOW_CLAZZ_SET); + } + + public static Set getAllowClassPattern() { + return Collections.unmodifiableSet(ALLOW_CLAZZ_PATTERN); + } + + public static Set getDenyClassPattern() { + return Collections.unmodifiableSet(DENY_CLAZZ_PATTERN); + } + + private static Class[] getBasicClassType() { + return new Class[] {Boolean.class, Byte.class, Character.class, Double.class, Float.class, Integer.class, + Long.class, Short.class, Number.class, Class.class, String.class}; + } + + private static Class[] getCollectionClassType() { + return new Class[] {ArrayList.class, LinkedList.class, HashSet.class, + LinkedHashSet.class, TreeSet.class, HashMap.class, LinkedHashMap.class, TreeMap.class}; + } + + private static String getSeataClassPattern() { + return "io.seata.*"; + } + + private static String[] getDenyClassPatternList() { + return new String[] {"javax.naming.InitialContext", "javax.net.ssl.*", "com.unboundid.ldap.*"}; + } + + private static Set> getProtocolType() { + Enumeration packageDir = null; + String packageName = "io.seata.core.protocol"; + Set> classNameSet = new HashSet<>(); + try { + packageDir = Thread.currentThread().getContextClassLoader().getResources(packageName.replace(".", "/")); + } catch (IOException ignore) { + } + while (packageDir.hasMoreElements()) { + String filePath = packageDir.nextElement().getFile(); + findProtocolClassByPackage(filePath, packageName, classNameSet); + } + return classNameSet; + } + + private static void findProtocolClassByPackage(String classPath, String rootPackageName, Set classNameSet) { + File file = new File(classPath); + if (!file.exists()) { + return; + } + if (file.isDirectory()) { + File[] files = file.listFiles(); + if (null == files) { + return; + } + for (File path : files) { + if (path.isDirectory()) { + findProtocolClassByPackage(path.getAbsolutePath(), rootPackageName + "." + path.getName(), + classNameSet); + } else { + findProtocolClassByPackage(path.getAbsolutePath(), rootPackageName, classNameSet); + } + } + } else { + if (matchProtocol(file.getName())) { + String className = file.getName().substring(0, file.getName().length() - CLASS_POSTFIX.length()); + try { + classNameSet.add( + Thread.currentThread().getContextClassLoader().loadClass(rootPackageName + '.' + className)); + } catch (ClassNotFoundException ignore) { + //ignore interface + } + } + } + } + + private static boolean matchProtocol(String fileName) { + if (!fileName.endsWith(CLASS_POSTFIX)) { + return false; + } + fileName = fileName.replace(CLASS_POSTFIX, ""); + if (fileName.startsWith(ABSTRACT_CLASS_ID)) { + return false; + } + if (fileName.contains(REQUEST_CLASS_ID) || fileName.contains(RESPONSE_CLASS_ID) || fileName.endsWith(MESSAGE_CLASS_ID)) { + return true; + } + return false; + } + + private static Class[] getProtocolInnerFields() { + return new Class[] {ResultCode.class, GlobalStatus.class, BranchStatus.class, BranchType.class, TransactionExceptionCode.class}; + } +} diff --git a/core/src/test/java/io/seata/core/serializer/SerializerSecurityRegistryTest.java b/core/src/test/java/io/seata/core/serializer/SerializerSecurityRegistryTest.java new file mode 100644 index 00000000000..19e8f8783a7 --- /dev/null +++ b/core/src/test/java/io/seata/core/serializer/SerializerSecurityRegistryTest.java @@ -0,0 +1,60 @@ +/* + * Copyright 1999-2019 Seata.io Group. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.seata.core.serializer; + +import io.seata.core.protocol.HeartbeatMessage; +import io.seata.core.protocol.Version; +import io.seata.core.protocol.transaction.AbstractBranchEndRequest; +import io.seata.core.protocol.transaction.BranchCommitRequest; +import io.seata.core.protocol.transaction.BranchCommitResponse; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +/** + * @author slievrly + */ +public class SerializerSecurityRegistryTest { + @Test + public void getAllowClassType() { + Assertions.assertTrue(SerializerSecurityRegistry.getAllowClassType().contains(Long.class)); + Assertions.assertTrue(SerializerSecurityRegistry.getAllowClassType().contains(Integer.class)); + Assertions.assertTrue(SerializerSecurityRegistry.getAllowClassType().contains(HeartbeatMessage.class)); + Assertions.assertTrue(SerializerSecurityRegistry.getAllowClassType().contains(BranchCommitRequest.class)); + Assertions.assertTrue(SerializerSecurityRegistry.getAllowClassType().contains(BranchCommitResponse.class)); + Assertions.assertFalse(SerializerSecurityRegistry.getAllowClassType().contains(AbstractBranchEndRequest.class)); + Assertions.assertFalse(SerializerSecurityRegistry.getAllowClassType().contains(Version.class)); + } + + @Test + public void getAllowClassPattern() { + Assertions.assertTrue( + SerializerSecurityRegistry.getAllowClassPattern().contains(Long.class.getCanonicalName())); + Assertions.assertTrue( + SerializerSecurityRegistry.getAllowClassPattern().contains(Integer.class.getCanonicalName())); + Assertions.assertTrue( + SerializerSecurityRegistry.getAllowClassPattern().contains(HeartbeatMessage.class.getCanonicalName())); + Assertions.assertTrue( + SerializerSecurityRegistry.getAllowClassPattern().contains(BranchCommitRequest.class.getCanonicalName())); + Assertions.assertTrue( + SerializerSecurityRegistry.getAllowClassPattern().contains(BranchCommitResponse.class.getCanonicalName())); + Assertions.assertFalse(SerializerSecurityRegistry.getAllowClassPattern() + .contains(AbstractBranchEndRequest.class.getCanonicalName())); + Assertions.assertFalse( + SerializerSecurityRegistry.getAllowClassPattern().contains(Version.class.getCanonicalName())); + Assertions.assertTrue(SerializerSecurityRegistry.getAllowClassPattern().contains("io.seata.*")); + } +} diff --git a/serializer/seata-serializer-fst/src/main/java/io/seata/serializer/fst/FstSerializerFactory.java b/serializer/seata-serializer-fst/src/main/java/io/seata/serializer/fst/FstSerializerFactory.java index 2e38d6b6bbd..8c1739d1e57 100644 --- a/serializer/seata-serializer-fst/src/main/java/io/seata/serializer/fst/FstSerializerFactory.java +++ b/serializer/seata-serializer-fst/src/main/java/io/seata/serializer/fst/FstSerializerFactory.java @@ -15,7 +15,7 @@ */ package io.seata.serializer.fst; -import io.seata.core.serializer.SerializerClassRegistry; +import io.seata.core.serializer.SerializerSecurityRegistry; import org.nustaq.serialization.FSTConfiguration; /** @@ -33,7 +33,7 @@ public static FstSerializerFactory getDefaultFactory() { } public FstSerializerFactory() { - SerializerClassRegistry.getRegisteredClasses().keySet().forEach(conf::registerClass); + SerializerSecurityRegistry.getAllowClassType().forEach(conf::registerClass); } public byte[] serialize(T t) { diff --git a/serializer/seata-serializer-hessian/src/main/java/io/seata/serializer/hessian/HessianSerializerFactory.java b/serializer/seata-serializer-hessian/src/main/java/io/seata/serializer/hessian/HessianSerializerFactory.java index 4fce9517d03..1399155c87e 100644 --- a/serializer/seata-serializer-hessian/src/main/java/io/seata/serializer/hessian/HessianSerializerFactory.java +++ b/serializer/seata-serializer-hessian/src/main/java/io/seata/serializer/hessian/HessianSerializerFactory.java @@ -15,19 +15,8 @@ */ package io.seata.serializer.hessian; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; -import java.util.TreeSet; - import com.caucho.hessian.io.SerializerFactory; +import io.seata.core.serializer.SerializerSecurityRegistry; /* * @Xin Wang @@ -37,59 +26,27 @@ public class HessianSerializerFactory extends SerializerFactory { private HessianSerializerFactory() { super(); + //Serialization whitelist super.getClassFactory().setWhitelist(true); - super.getClassFactory().allow("io.seata.*"); - allowBasicTypes(); - allowCollections(); - denyTypes(); + //register allow types + registerAllowTypes(); + //register deny types + registerDenyTypes(); } public static SerializerFactory getInstance() { return INSTANCE; } - private void allowBasicTypes() { - super.getClassFactory().allow(boolean.class.getCanonicalName()); - super.getClassFactory().allow(byte.class.getCanonicalName()); - super.getClassFactory().allow(char.class.getCanonicalName()); - super.getClassFactory().allow(double.class.getCanonicalName()); - super.getClassFactory().allow(float.class.getCanonicalName()); - super.getClassFactory().allow(int.class.getCanonicalName()); - super.getClassFactory().allow(long.class.getCanonicalName()); - super.getClassFactory().allow(short.class.getCanonicalName()); - super.getClassFactory().allow(Boolean.class.getCanonicalName()); - super.getClassFactory().allow(Byte.class.getCanonicalName()); - super.getClassFactory().allow(Character.class.getCanonicalName()); - super.getClassFactory().allow(Double.class.getCanonicalName()); - super.getClassFactory().allow(Float.class.getCanonicalName()); - super.getClassFactory().allow(Integer.class.getCanonicalName()); - super.getClassFactory().allow(Long.class.getCanonicalName()); - super.getClassFactory().allow(Short.class.getCanonicalName()); - - super.getClassFactory().allow(Number.class.getCanonicalName()); - super.getClassFactory().allow(Class.class.getCanonicalName()); - super.getClassFactory().allow(String.class.getCanonicalName()); - } - - private void allowCollections() { - super.getClassFactory().allow(List.class.getCanonicalName()); - super.getClassFactory().allow(ArrayList.class.getCanonicalName()); - super.getClassFactory().allow(LinkedList.class.getCanonicalName()); - - super.getClassFactory().allow(Set.class.getCanonicalName()); - super.getClassFactory().allow(HashSet.class.getCanonicalName()); - super.getClassFactory().allow(LinkedHashSet.class.getCanonicalName()); - super.getClassFactory().allow(TreeSet.class.getCanonicalName()); - - super.getClassFactory().allow(Map.class.getCanonicalName()); - super.getClassFactory().allow(HashMap.class.getCanonicalName()); - super.getClassFactory().allow(LinkedHashMap.class.getCanonicalName()); - super.getClassFactory().allow(TreeMap.class.getCanonicalName()); + private void registerAllowTypes() { + for (String pattern : SerializerSecurityRegistry.getAllowClassPattern()) { + super.getClassFactory().allow(pattern); + } } - private void denyTypes() { - super.getClassFactory().deny("javax.naming.InitialContext"); - super.getClassFactory().deny("javax.net.ssl.*"); - super.getClassFactory().deny("com.unboundid.ldap.*"); + private void registerDenyTypes() { + for (String pattern : SerializerSecurityRegistry.getDenyClassPattern()) { + super.getClassFactory().deny(pattern); + } } } diff --git a/serializer/seata-serializer-kryo/src/main/java/io/seata/serializer/kryo/KryoSerializerFactory.java b/serializer/seata-serializer-kryo/src/main/java/io/seata/serializer/kryo/KryoSerializerFactory.java index c9b3c93925f..e35af2687f0 100644 --- a/serializer/seata-serializer-kryo/src/main/java/io/seata/serializer/kryo/KryoSerializerFactory.java +++ b/serializer/seata-serializer-kryo/src/main/java/io/seata/serializer/kryo/KryoSerializerFactory.java @@ -15,23 +15,9 @@ */ package io.seata.serializer.kryo; -import java.lang.reflect.InvocationHandler; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.net.URI; -import java.util.Arrays; -import java.util.BitSet; -import java.util.UUID; -import java.util.regex.Pattern; import com.esotericsoftware.kryo.Kryo; -import com.esotericsoftware.kryo.serializers.DefaultSerializers; import com.esotericsoftware.kryo.util.Pool; -import de.javakaffee.kryoserializers.BitSetSerializer; -import de.javakaffee.kryoserializers.JdkProxySerializer; -import de.javakaffee.kryoserializers.RegexSerializer; -import de.javakaffee.kryoserializers.URISerializer; -import de.javakaffee.kryoserializers.UUIDSerializer; -import io.seata.core.serializer.SerializerClassRegistry; +import io.seata.core.serializer.SerializerSecurityRegistry; /** * @author jsbxyyx @@ -46,20 +32,12 @@ public class KryoSerializerFactory { protected Kryo create() { Kryo kryo = new Kryo(); kryo.setReferences(true); - kryo.setRegistrationRequired(false); - // register serializer - kryo.register(Arrays.asList("").getClass()); - kryo.register(InvocationHandler.class, new JdkProxySerializer()); - kryo.register(BigDecimal.class, new DefaultSerializers.BigDecimalSerializer()); - kryo.register(BigInteger.class, new DefaultSerializers.BigIntegerSerializer()); - kryo.register(Pattern.class, new RegexSerializer()); - kryo.register(BitSet.class, new BitSetSerializer()); - kryo.register(URI.class, new URISerializer()); - kryo.register(UUID.class, new UUIDSerializer()); + //Serialization whitelist + kryo.setRegistrationRequired(true); - // register commonly class - SerializerClassRegistry.getRegisteredClasses().keySet().forEach(kryo::register); + // register allow class + SerializerSecurityRegistry.getAllowClassType().forEach(kryo::register); return kryo; } }; diff --git a/server/src/main/resources/application.yml b/server/src/main/resources/application.yml index 7bbd4a1e1ff..8f3149bd465 100644 --- a/server/src/main/resources/application.yml +++ b/server/src/main/resources/application.yml @@ -44,8 +44,8 @@ seata: store: # support: file 、 db 、 redis mode: file -# server: -# service-port: 8091 #If not configured, the default is '${server.port} + 1000' + # server: + # service-port: 8091 #If not configured, the default is '${server.port} + 1000' security: secretKey: SeataSecretKey0c382ef121d778043159209298fd40bf3850a017 tokenValidityInMilliseconds: 1800000