CVE-2026-7045
Description
A vulnerability was determined in baomidou dynamic-datasource 2.5.0. Affected by this vulnerability is the function DsSpelExpressionProcessor#doDetermineDatasource of the file dynamic-datasource-spring/src/main/java/com/baomidou/dynamic/datasource/processor/DsSpelExpressionProcessor.java of the component StandardEvaluationContext/SpelExpressionParser. This manipulation causes injection. The attack may be initiated remotely. Patch name: 273fcedaee984c08197c0890f14190b86ab7e0b8. It is recommended to apply a patch to fix this issue.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
com.baomidou:dynamic-datasource-springMaven | <= 4.5.0 | — |
Affected products
1Patches
1273fcedaee98Fix SpEL injection (potential RCE) in DsSpelExpressionProcessor (#767)
6 files changed · +132 −0
dynamic-datasource-spring-boot3-starter/src/main/java/com/baomidou/dynamic/datasource/spring/boot/autoconfigure/DynamicDataSourceAopConfiguration.java+1 −0 modified@@ -66,6 +66,7 @@ public DsProcessor dsProcessor(BeanFactory beanFactory) { DsProcessor sessionProcessor = new DsJakartaSessionProcessor(); DsSpelExpressionProcessor spelExpressionProcessor = new DsSpelExpressionProcessor(); spelExpressionProcessor.setBeanResolver(new BeanFactoryResolver(beanFactory)); + spelExpressionProcessor.setAllowedSpelTypeAccess(properties.getAop().getAllowedSpelTypeAccess()); headerProcessor.setNextProcessor(sessionProcessor); sessionProcessor.setNextProcessor(spelExpressionProcessor); return headerProcessor;
dynamic-datasource-spring-boot3-starter/src/test/java/com/baomidou/dynamic/datasource/common/v3/DsSpelExpressionProcessorSecurityTest.java+89 −0 added@@ -0,0 +1,89 @@ +/* + * Copyright © 2018 organization baomidou + * + * 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 com.baomidou.dynamic.datasource.common.v3; + +import com.baomidou.dynamic.datasource.processor.DsSpelExpressionProcessor; +import org.aopalliance.intercept.MethodInvocation; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.expression.EvaluationException; + +import java.lang.reflect.Method; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +/** + * Security tests for {@link DsSpelExpressionProcessor} verifying that SpEL injection via + * type references (T(...)) is blocked to prevent Remote Code Execution, and that the + * behaviour can be restored by explicitly enabling {@code allowedSpelTypeAccess}. + */ +class DsSpelExpressionProcessorSecurityTest { + + private DsSpelExpressionProcessor processor; + private MethodInvocation invocation; + + @BeforeEach + void setUp() throws Exception { + processor = new DsSpelExpressionProcessor(); + + Method method = SampleService.class.getMethod("getByTenant", String.class); + invocation = mock(MethodInvocation.class); + when(invocation.getMethod()).thenReturn(method); + when(invocation.getArguments()).thenReturn(new Object[]{"tenant1"}); + when(invocation.getThis()).thenReturn(new SampleService()); + } + + @Test + void normalSpelExpressionShouldWork() { + // #tenant reads the method parameter value normally + String result = processor.doDetermineDatasource(invocation, "#tenant"); + assertEquals("tenant1", result); + } + + @Test + void typeReferenceExpressionShouldBeBlockedByDefault() { + // T(...) type references must be blocked to prevent SpEL injection / RCE + assertThrows(EvaluationException.class, () -> + processor.doDetermineDatasource(invocation, "T(java.lang.Runtime).getRuntime().exec('id')") + ); + } + + @Test + void newInstanceExpressionShouldBeBlockedByDefault() { + // new Type(...) constructor invocations must also be blocked + assertThrows(EvaluationException.class, () -> + processor.doDetermineDatasource(invocation, "new java.lang.ProcessBuilder('id').start()") + ); + } + + @Test + void typeReferenceExpressionShouldWorkWhenExplicitlyAllowed() { + // When allowedSpelTypeAccess=true, T(...) expressions are permitted (opt-in unsafe mode) + processor.setAllowedSpelTypeAccess(true); + // T(java.lang.String) is a safe type reference to verify the restriction is lifted + String result = processor.doDetermineDatasource(invocation, "T(java.lang.String).valueOf(#tenant)"); + assertEquals("tenant1", result); + } + + static class SampleService { + public String getByTenant(String tenant) { + return tenant; + } + } +}
dynamic-datasource-spring-boot4-starter/src/main/java/com/baomidou/dynamic/datasource/spring/boot/autoconfigure/DynamicDataSourceAopConfiguration.java+1 −0 modified@@ -66,6 +66,7 @@ public DsProcessor dsProcessor(BeanFactory beanFactory) { DsProcessor sessionProcessor = new DsJakartaSessionProcessor(); DsSpelExpressionProcessor spelExpressionProcessor = new DsSpelExpressionProcessor(); spelExpressionProcessor.setBeanResolver(new BeanFactoryResolver(beanFactory)); + spelExpressionProcessor.setAllowedSpelTypeAccess(properties.getAop().getAllowedSpelTypeAccess()); headerProcessor.setNextProcessor(sessionProcessor); sessionProcessor.setNextProcessor(spelExpressionProcessor); return headerProcessor;
dynamic-datasource-spring-boot-common/src/main/java/com/baomidou/dynamic/datasource/spring/boot/autoconfigure/DynamicDatasourceAopProperties.java+8 −0 modified@@ -38,4 +38,12 @@ public class DynamicDatasourceAopProperties { * aop allowedPublicOnly */ private Boolean allowedPublicOnly = true; + /** + * Whether to allow SpEL type references (e.g. T(java.lang.Runtime)) and constructor + * expressions in datasource key expressions resolved by DsSpelExpressionProcessor. + * Defaults to false (restricted / safe mode) to prevent SpEL injection attacks. + * Set to true only if your application genuinely requires such expressions and you + * fully understand the security risk. + */ + private Boolean allowedSpelTypeAccess = false; } \ No newline at end of file
dynamic-datasource-spring-boot-starter/src/main/java/com/baomidou/dynamic/datasource/spring/boot/autoconfigure/DynamicDataSourceAopConfiguration.java+1 −0 modified@@ -66,6 +66,7 @@ public DsProcessor dsProcessor(BeanFactory beanFactory) { DsProcessor sessionProcessor = new DsSessionProcessor(); DsSpelExpressionProcessor spelExpressionProcessor = new DsSpelExpressionProcessor(); spelExpressionProcessor.setBeanResolver(new BeanFactoryResolver(beanFactory)); + spelExpressionProcessor.setAllowedSpelTypeAccess(properties.getAop().getAllowedSpelTypeAccess()); headerProcessor.setNextProcessor(sessionProcessor); sessionProcessor.setNextProcessor(spelExpressionProcessor); return headerProcessor;
dynamic-datasource-spring/src/main/java/com/baomidou/dynamic/datasource/processor/DsSpelExpressionProcessor.java+32 −0 modified@@ -22,12 +22,14 @@ import org.springframework.core.DefaultParameterNameDiscoverer; import org.springframework.core.ParameterNameDiscoverer; import org.springframework.expression.BeanResolver; +import org.springframework.expression.EvaluationException; import org.springframework.expression.ExpressionParser; import org.springframework.expression.ParserContext; import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.expression.spel.support.StandardEvaluationContext; import java.lang.reflect.Method; +import java.util.Collections; /** * SpEL表达式处理器 @@ -69,6 +71,18 @@ public String getExpressionSuffix() { } }; private BeanResolver beanResolver; + /** + * Whether to allow SpEL type references (e.g. {@code T(java.lang.Runtime)}) and constructor + * expressions in datasource key expressions. + * <p> + * Defaults to {@code false} (restricted / safe mode). When {@code false}, any attempt to use + * {@code T(...)} type-references or {@code new} constructor expressions will throw an + * {@link EvaluationException}, preventing potential SpEL-injection / RCE attacks. + * <p> + * Set to {@code true} only if your application genuinely requires such expressions and you + * fully understand the security implications. + */ + private boolean allowedSpelTypeAccess = false; @Override public boolean matches(String key) { @@ -82,10 +96,28 @@ public String doDetermineDatasource(MethodInvocation invocation, String key) { ExpressionRootObject rootObject = new ExpressionRootObject(method, arguments, invocation.getThis()); StandardEvaluationContext context = new MethodBasedEvaluationContext(rootObject, method, arguments, NAME_DISCOVERER); context.setBeanResolver(beanResolver); + if (!allowedSpelTypeAccess) { + // Prevent SpEL injection: block T(...) type references and new instance creation + context.setTypeLocator(typeName -> { + throw new EvaluationException("Type access is not allowed in DS SpEL expressions: " + typeName); + }); + context.setConstructorResolvers(Collections.emptyList()); + } final Object value = PARSER.parseExpression(key, parserContext).getValue(context); return value == null ? null : value.toString(); } + /** + * Allow or restrict SpEL type references ({@code T(...)}) and constructor expressions in + * datasource key resolution. Defaults to {@code false} (restricted). Enable only when + * strictly necessary and you accept the associated security risk. + * + * @param allowedSpelTypeAccess {@code true} to allow type access, {@code false} to block it + */ + public void setAllowedSpelTypeAccess(boolean allowedSpelTypeAccess) { + this.allowedSpelTypeAccess = allowedSpelTypeAccess; + } + /** * 设置解析上下文 *
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
8- github.com/advisories/GHSA-6rmm-pg23-5f8qghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2026-7045ghsaADVISORY
- github.com/baomidou/dynamic-datasource/commit/273fcedaee984c08197c0890f14190b86ab7e0b8nvdWEB
- github.com/baomidou/dynamic-datasource/issues/766nvdWEB
- github.com/baomidou/dynamic-datasource/pull/767nvdWEB
- vuldb.com/submit/798600nvdWEB
- vuldb.com/vuln/359624nvdWEB
- vuldb.com/vuln/359624/ctinvdWEB
News mentions
0No linked articles in our index yet.