Apache Dubbo default deserialization protocol Hessian2 cause CRE
Description
A deserialization vulnerability existed in dubbo 2.7.5 and its earlier versions, which could lead to malicious code execution. Most Dubbo users use Hessian2 as the default serialization/deserialization protool, during Hessian2 deserializing the HashMap object, some functions in the classes stored in HasMap will be executed after a series of program calls, however, those special functions may cause remote command execution. For example, the hashCode() function of the EqualsBean class in rome-1.7.0.jar will cause the remotely load malicious classes and execute malicious code by constructing a malicious request. This issue was fixed in Apache Dubbo 2.6.9 and 2.7.8.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
A deserialization vulnerability in Apache Dubbo 2.7.5 and earlier allows remote code execution via crafted Hessian2 requests.
Description
CVE-2020-11995 is a deserialization vulnerability in Apache Dubbo versions 2.7.5 and earlier. The flaw resides in the Hessian2 serialization/deserialization protocol, which is commonly used by Dubbo. When deserializing a HashMap object, certain functions in the classes stored in the map are executed. This can be exploited by crafting a malicious request that triggers the hashCode() method of a class like EqualsBean from the Rome library, leading to remote code execution [1].
Exploitation
An attacker can exploit this vulnerability by sending a specially crafted RPC request to a Dubbo service. The attack relies on the presence of specific gadget classes in the classpath, such as those from the Rome library. No authentication is required, and the attack can be carried out over the network, making it easily exploitable [1].
Impact
Successful exploitation allows an attacker to execute arbitrary code on the target system, potentially leading to full compromise of the Dubbo server and any data it processes [1].
Mitigation
The vulnerability has been patched in Apache Dubbo versions 2.6.9 and 2.7.8. The fix introduces a whitelist mechanism for deserialization, as seen in the commit that adds a Hessian2FactoryInitializer interface with allow/deny lists [2]. Users are strongly advised to upgrade to these patched versions or apply the necessary workarounds [1][2].
AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
org.apache.dubbo:dubbo-parentMaven | >= 2.7.0, < 2.7.8 | 2.7.8 |
org.apache.dubbo:dubbo-parentMaven | < 2.6.9 | 2.6.9 |
Affected products
3- Apache Software Foundation/Apache Dubbov5Range: Apache Dubbo
Patches
1d2e9baf38010Hessian2 whitelist (#6378) (#6415)
12 files changed · +174 −11
dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/DubboBootstrap.java+7 −3 modified@@ -127,7 +127,7 @@ public class DubboBootstrap extends GenericEventListener { private final Logger logger = LoggerFactory.getLogger(getClass()); - private static DubboBootstrap instance; + private static volatile DubboBootstrap instance; private final AtomicBoolean awaited = new AtomicBoolean(false); @@ -176,9 +176,13 @@ public class DubboBootstrap extends GenericEventListener { /** * See {@link ApplicationModel} and {@link ExtensionLoader} for why DubboBootstrap is designed to be singleton. */ - public static synchronized DubboBootstrap getInstance() { + public static DubboBootstrap getInstance() { if (instance == null) { - instance = new DubboBootstrap(); + synchronized (DubboBootstrap.class) { + if (instance == null) { + instance = new DubboBootstrap(); + } + } } return instance; }
dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/annotation/EnableDubboConfig.java+1 −1 modified@@ -72,7 +72,7 @@ /** * It indicates whether binding to multiple Spring Beans. * - * @return the default value is <code>false</code> + * @return the default value is <code>true</code> * @revised 2.5.9 */ boolean multiple() default true;
dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/annotation/EnableDubbo.java+1 −1 modified@@ -72,7 +72,7 @@ /** * It indicates whether {@link AbstractConfig} binding to multiple Spring Beans. * - * @return the default value is <code>false</code> + * @return the default value is <code>true</code> * @see EnableDubboConfig#multiple() */ @AliasFor(annotation = EnableDubboConfig.class, attribute = "multiple")
dubbo-dependencies-bom/pom.xml+1 −1 modified@@ -152,7 +152,7 @@ <activation_version>1.2.0</activation_version> <test_container_version>1.11.2</test_container_version> <etcd_launcher_version>0.3.0</etcd_launcher_version> - <hessian_lite_version>3.2.7</hessian_lite_version> + <hessian_lite_version>3.2.8</hessian_lite_version> <swagger_version>1.5.19</swagger_version> <spring_test_version>4.3.16.RELEASE</spring_test_version>
dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/dubbo/AbstractHessian2FactoryInitializer.java+36 −0 added@@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.dubbo.common.serialize.hessian2.dubbo; + +import com.alibaba.com.caucho.hessian.io.SerializerFactory; + +public abstract class AbstractHessian2FactoryInitializer implements Hessian2FactoryInitializer { + private static SerializerFactory SERIALIZER_FACTORY; + + @Override + public SerializerFactory getSerializerFactory() { + if (SERIALIZER_FACTORY != null) { + return SERIALIZER_FACTORY; + } + synchronized (this) { + SERIALIZER_FACTORY = createSerializerFactory(); + } + return SERIALIZER_FACTORY; + } + + protected abstract SerializerFactory createSerializerFactory(); +}
dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/dubbo/DefaultHessian2FactoryInitializer.java+28 −0 added@@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.dubbo.common.serialize.hessian2.dubbo; + +import org.apache.dubbo.common.serialize.hessian2.Hessian2SerializerFactory; + +import com.alibaba.com.caucho.hessian.io.SerializerFactory; + +public class DefaultHessian2FactoryInitializer extends AbstractHessian2FactoryInitializer { + @Override + protected SerializerFactory createSerializerFactory() { + return new Hessian2SerializerFactory(); + } +}
dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/dubbo/Hessian2FactoryInitializer.java+43 −0 added@@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.dubbo.common.serialize.hessian2.dubbo; + +import org.apache.dubbo.common.config.ConfigurationUtils; +import org.apache.dubbo.common.extension.ExtensionLoader; +import org.apache.dubbo.common.extension.SPI; +import org.apache.dubbo.common.utils.StringUtils; + +import com.alibaba.com.caucho.hessian.io.SerializerFactory; + +@SPI("default") +public interface Hessian2FactoryInitializer { + String WHITELIST = "dubbo.application.hessian2.whitelist"; + String ALLOW = "dubbo.application.hessian2.allow"; + String DENY = "dubbo.application.hessian2.deny"; + ExtensionLoader<Hessian2FactoryInitializer> loader = ExtensionLoader.getExtensionLoader(Hessian2FactoryInitializer.class); + + SerializerFactory getSerializerFactory(); + + static Hessian2FactoryInitializer getInstance() { + String whitelist = ConfigurationUtils.getProperty(WHITELIST); + if (StringUtils.isNotEmpty(whitelist)) { + return loader.getExtension("whitelist"); + } + return loader.getDefaultExtension(); + } + +}
dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/dubbo/WhitelistHessian2FactoryInitializer.java+50 −0 added@@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.dubbo.common.serialize.hessian2.dubbo; + +import org.apache.dubbo.common.config.ConfigurationUtils; +import org.apache.dubbo.common.serialize.hessian2.Hessian2SerializerFactory; +import org.apache.dubbo.common.utils.StringUtils; + +import com.alibaba.com.caucho.hessian.io.SerializerFactory; + +/** + * see https://github.com/ebourg/hessian/commit/cf851f5131707891e723f7f6a9718c2461aed826 + */ +public class WhitelistHessian2FactoryInitializer extends AbstractHessian2FactoryInitializer { + + @Override + public SerializerFactory createSerializerFactory() { + SerializerFactory serializerFactory = new Hessian2SerializerFactory(); + String whiteList = ConfigurationUtils.getProperty(WHITELIST); + if ("true".equals(whiteList)) { + serializerFactory.getClassFactory().setWhitelist(true); + String allowPattern = ConfigurationUtils.getProperty(ALLOW); + if (StringUtils.isNotEmpty(allowPattern)) { + serializerFactory.getClassFactory().allow(allowPattern); + } + } else { + serializerFactory.getClassFactory().setWhitelist(false); + String denyPattern = ConfigurationUtils.getProperty(DENY); + if (StringUtils.isNotEmpty(denyPattern)) { + serializerFactory.getClassFactory().deny(denyPattern); + } + } + return serializerFactory; + } + +}
dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ObjectInput.java+2 −1 modified@@ -17,6 +17,7 @@ package org.apache.dubbo.common.serialize.hessian2; import org.apache.dubbo.common.serialize.ObjectInput; +import org.apache.dubbo.common.serialize.hessian2.dubbo.Hessian2FactoryInitializer; import com.alibaba.com.caucho.hessian.io.Hessian2Input; @@ -31,7 +32,7 @@ public class Hessian2ObjectInput implements ObjectInput { private static ThreadLocal<Hessian2Input> INPUT_TL = ThreadLocal.withInitial(() -> { Hessian2Input h2i = new Hessian2Input(null); - h2i.setSerializerFactory(Hessian2SerializerFactory.SERIALIZER_FACTORY); + h2i.setSerializerFactory(Hessian2FactoryInitializer.getInstance().getSerializerFactory()); h2i.setCloseStreamOnClose(true); return h2i; });
dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ObjectOutput.java+2 −1 modified@@ -17,6 +17,7 @@ package org.apache.dubbo.common.serialize.hessian2; import org.apache.dubbo.common.serialize.ObjectOutput; +import org.apache.dubbo.common.serialize.hessian2.dubbo.Hessian2FactoryInitializer; import com.alibaba.com.caucho.hessian.io.Hessian2Output; @@ -30,7 +31,7 @@ public class Hessian2ObjectOutput implements ObjectOutput { private static ThreadLocal<Hessian2Output> OUTPUT_TL = ThreadLocal.withInitial(() -> { Hessian2Output h2o = new Hessian2Output(null); - h2o.setSerializerFactory(Hessian2SerializerFactory.SERIALIZER_FACTORY); + h2o.setSerializerFactory(Hessian2FactoryInitializer.getInstance().getSerializerFactory()); h2o.setCloseStreamOnClose(true); return h2o; });
dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2SerializerFactory.java+1 −3 modified@@ -20,9 +20,7 @@ public class Hessian2SerializerFactory extends SerializerFactory { - public static final SerializerFactory SERIALIZER_FACTORY = new Hessian2SerializerFactory(); - - private Hessian2SerializerFactory() { + public Hessian2SerializerFactory() { } @Override
dubbo-serialization/dubbo-serialization-hessian2/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.serialize.hessian2.dubbo.Hessian2FactoryInitializer+2 −0 added@@ -0,0 +1,2 @@ +default=org.apache.dubbo.common.serialize.hessian2.dubbo.DefaultHessian2FactoryInitializer +whitelist=org.apache.dubbo.common.serialize.hessian2.dubbo.WhitelistHessian2FactoryInitializer \ No newline at end of file
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
4- github.com/advisories/GHSA-74mg-6xqx-2vrqghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2020-11995ghsaADVISORY
- github.com/apache/dubbo/commit/d2e9baf380108950c48e0ab700ccdbf11dd753abghsaWEB
- lists.apache.org/thread.html/r5b2df4ef479209dc4ced457b3d58a887763b60b9354c3dc148b2eb5b%40%3Cdev.dubbo.apache.org%3Eghsax_refsource_MISCWEB
News mentions
0No linked articles in our index yet.