CVE-2023-20863
Description
Spring Framework SpEL parsing flaw allows crafted expressions to cause denial-of-service via excessive resource consumption.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Spring Framework SpEL parsing flaw allows crafted expressions to cause denial-of-service via excessive resource consumption.
Vulnerability
CVE-2023-20863 is a denial-of-service vulnerability in Spring Framework's SpEL (Spring Expression Language) parsing. The flaw arises because prior to versions 5.2.24, 5.3.27, and 6.0.8, there was no limit on the length of a SpEL expression. An attacker can supply a carefully crafted, overly long SpEL expression that, when parsed, consumes excessive CPU and memory resources, leading to a denial-of-service condition [1].
Exploitation
The vulnerability can be exploited by any user able to provide a SpEL expression to a Spring application, such as through web requests or data binding. No prior authentication is required if the application exposes SpEL evaluation to untrusted inputs. The attacker simply needs to submit a specially crafted, very long expression to trigger the resource exhaustion [1].
Impact
Successful exploitation results in a denial-of-service, making the application unresponsive or crashing it. There is no evidence of data leakage or remote code execution from this vulnerability, as the impact is limited to availability [1].
Mitigation
The Spring Framework team patched the issue by introducing a maximum expression length check in InternalSpelExpressionParser [2][3][4]. Users should upgrade to Spring Framework 5.2.24, 5.3.27, 6.0.8, or later. For those unable to upgrade, a custom SpEL parser configuration can enforce a length limit. The fix is included in the corresponding Spring Boot versions (2.5.14, 2.6.12, 2.7.6, and 3.0.3).
AI Insight generated on May 20, 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.springframework:spring-expressionMaven | >= 6.0.0, < 6.0.8 | 6.0.8 |
org.springframework:spring-expressionMaven | >= 5.3.0, < 5.3.27 | 5.3.27 |
org.springframework:spring-expressionMaven | < 5.2.24.RELEASE | 5.2.24.RELEASE |
Affected products
2- spring framework/spring frameworkdescription
Patches
3ebc82654282bLimit SpEL expression length
3 files changed · +45 −11
spring-expression/src/main/java/org/springframework/expression/spel/SpelMessage.java+7 −3 modified@@ -268,15 +268,19 @@ public enum SpelMessage { /** @since 5.2.23 */ MAX_REPEATED_TEXT_SIZE_EXCEEDED(Kind.ERROR, 1076, - "Repeated text results in too many characters, exceeding the threshold of ''{0}''"), + "Repeated text is too long, exceeding the threshold of ''{0}'' characters"), /** @since 5.2.23 */ MAX_REGEX_LENGTH_EXCEEDED(Kind.ERROR, 1077, - "Regular expression contains too many characters, exceeding the threshold of ''{0}''"), + "Regular expression is too long, exceeding the threshold of ''{0}'' characters"), /** @since 5.2.24 */ MAX_CONCATENATED_STRING_LENGTH_EXCEEDED(Kind.ERROR, 1078, - "Concatenated string is too long, exceeding the threshold of ''{0}'' characters"); + "Concatenated string is too long, exceeding the threshold of ''{0}'' characters"), + + /** @since 5.2.24 */ + MAX_EXPRESSION_LENGTH_EXCEEDED(Kind.ERROR, 1079, + "SpEL expression is too long, exceeding the threshold of ''{0}'' characters"); private final Kind kind;
spring-expression/src/main/java/org/springframework/expression/spel/standard/InternalSpelExpressionParser.java+15 −0 modified@@ -29,6 +29,7 @@ import org.springframework.expression.ParserContext; import org.springframework.expression.common.TemplateAwareExpressionParser; import org.springframework.expression.spel.InternalParseException; +import org.springframework.expression.spel.SpelEvaluationException; import org.springframework.expression.spel.SpelMessage; import org.springframework.expression.spel.SpelParseException; import org.springframework.expression.spel.SpelParserConfiguration; @@ -92,6 +93,12 @@ class InternalSpelExpressionParser extends TemplateAwareExpressionParser { private static final Pattern VALID_QUALIFIED_ID_PATTERN = Pattern.compile("[\\p{L}\\p{N}_$]+"); + /** + * Maximum length permitted for a SpEL expression. + * @since 5.2.24 + */ + private static final int MAX_EXPRESSION_LENGTH = 10_000; + private final SpelParserConfiguration configuration; @@ -127,6 +134,8 @@ public InternalSpelExpressionParser(SpelParserConfiguration configuration) { protected SpelExpression doParseExpression(String expressionString, @Nullable ParserContext context) throws ParseException { + checkExpressionLength(expressionString); + try { this.expressionString = expressionString; Tokenizer tokenizer = new Tokenizer(expressionString); @@ -148,6 +157,12 @@ protected SpelExpression doParseExpression(String expressionString, @Nullable Pa } } + private void checkExpressionLength(String string) { + if (string.length() > MAX_EXPRESSION_LENGTH) { + throw new SpelEvaluationException(SpelMessage.MAX_EXPRESSION_LENGTH_EXCEEDED, MAX_EXPRESSION_LENGTH); + } + } + // expression // : logicalOrExpression // ( (ASSIGN^ logicalOrExpression)
spring-expression/src/test/java/org/springframework/expression/spel/EvaluationTests.java+23 −8 modified@@ -60,6 +60,20 @@ class EvaluationTests extends AbstractExpressionTests { @Nested class MiscellaneousTests { + @Test + void expressionLength() { + String expression = String.format("'X' + '%s'", repeat(" ", 9_992)); + assertThat(expression).hasSize(10_000); + Expression expr = parser.parseExpression(expression); + String result = expr.getValue(context, String.class); + assertThat(result).hasSize(9_993); + assertThat(result.trim()).isEqualTo("X"); + + expression = String.format("'X' + '%s'", repeat(" ", 9_993)); + assertThat(expression).hasSize(10_001); + evaluateAndCheckError(expression, String.class, SpelMessage.MAX_EXPRESSION_LENGTH_EXCEEDED); + } + @Test void createListsOnAttemptToIndexNull01() throws EvaluationException, ParseException { ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true)); @@ -492,14 +506,6 @@ void matchesWithPatternLengthThreshold() { evaluateAndCheckError("'abc' matches '" + pattern + "'", Boolean.class, SpelMessage.MAX_REGEX_LENGTH_EXCEEDED); } - private String repeat(String str, int count) { - String result = ""; - for (int i = 0; i < count; i++) { - result += str; - } - return result; - } - } @Nested @@ -1474,6 +1480,15 @@ private void expectFail(ExpressionParser parser, EvaluationContext eContext, Str } + private static String repeat(String str, int count) { + String result = ""; + for (int i = 0; i < count; i++) { + result += str; + } + return result; + } + + @SuppressWarnings("rawtypes") static class TestClass {
965a6392757dLimit SpEL expression length
3 files changed · +45 −11
spring-expression/src/main/java/org/springframework/expression/spel/SpelMessage.java+7 −3 modified@@ -264,15 +264,19 @@ public enum SpelMessage { /** @since 5.2.23 */ MAX_REPEATED_TEXT_SIZE_EXCEEDED(Kind.ERROR, 1076, - "Repeated text results in too many characters, exceeding the threshold of ''{0}''"), + "Repeated text is too long, exceeding the threshold of ''{0}'' characters"), /** @since 5.2.23 */ MAX_REGEX_LENGTH_EXCEEDED(Kind.ERROR, 1077, - "Regular expression contains too many characters, exceeding the threshold of ''{0}''"), + "Regular expression is too long, exceeding the threshold of ''{0}'' characters"), /** @since 5.2.24 */ MAX_CONCATENATED_STRING_LENGTH_EXCEEDED(Kind.ERROR, 1078, - "Concatenated string is too long, exceeding the threshold of ''{0}'' characters"); + "Concatenated string is too long, exceeding the threshold of ''{0}'' characters"), + + /** @since 5.2.24 */ + MAX_EXPRESSION_LENGTH_EXCEEDED(Kind.ERROR, 1079, + "SpEL expression is too long, exceeding the threshold of ''{0}'' characters"); private final Kind kind;
spring-expression/src/main/java/org/springframework/expression/spel/standard/InternalSpelExpressionParser.java+15 −0 modified@@ -29,6 +29,7 @@ import org.springframework.expression.ParserContext; import org.springframework.expression.common.TemplateAwareExpressionParser; import org.springframework.expression.spel.InternalParseException; +import org.springframework.expression.spel.SpelEvaluationException; import org.springframework.expression.spel.SpelMessage; import org.springframework.expression.spel.SpelParseException; import org.springframework.expression.spel.SpelParserConfiguration; @@ -92,6 +93,12 @@ class InternalSpelExpressionParser extends TemplateAwareExpressionParser { private static final Pattern VALID_QUALIFIED_ID_PATTERN = Pattern.compile("[\\p{L}\\p{N}_$]+"); + /** + * Maximum length permitted for a SpEL expression. + * @since 5.2.24 + */ + private static final int MAX_EXPRESSION_LENGTH = 10_000; + private final SpelParserConfiguration configuration; @@ -127,6 +134,8 @@ public InternalSpelExpressionParser(SpelParserConfiguration configuration) { protected SpelExpression doParseExpression(String expressionString, @Nullable ParserContext context) throws ParseException { + checkExpressionLength(expressionString); + try { this.expressionString = expressionString; Tokenizer tokenizer = new Tokenizer(expressionString); @@ -148,6 +157,12 @@ protected SpelExpression doParseExpression(String expressionString, @Nullable Pa } } + private void checkExpressionLength(String string) { + if (string.length() > MAX_EXPRESSION_LENGTH) { + throw new SpelEvaluationException(SpelMessage.MAX_EXPRESSION_LENGTH_EXCEEDED, MAX_EXPRESSION_LENGTH); + } + } + // expression // : logicalOrExpression // ( (ASSIGN^ logicalOrExpression)
spring-expression/src/test/java/org/springframework/expression/spel/EvaluationTests.java+23 −8 modified@@ -59,6 +59,20 @@ */ public class EvaluationTests extends AbstractExpressionTests { + @Test + void expressionLength() { + String expression = String.format("'X' + '%s'", repeat(" ", 9_992)); + assertThat(expression).hasSize(10_000); + Expression expr = parser.parseExpression(expression); + String result = expr.getValue(context, String.class); + assertThat(result).hasSize(9_993); + assertThat(result.trim()).isEqualTo("X"); + + expression = String.format("'X' + '%s'", repeat(" ", 9_993)); + assertThat(expression).hasSize(10_001); + evaluateAndCheckError(expression, String.class, SpelMessage.MAX_EXPRESSION_LENGTH_EXCEEDED); + } + @Test public void testCreateListsOnAttemptToIndexNull01() throws EvaluationException, ParseException { ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true)); @@ -211,14 +225,6 @@ void matchesWithPatternLengthThreshold() { evaluateAndCheckError("'abc' matches '" + pattern + "'", Boolean.class, SpelMessage.MAX_REGEX_LENGTH_EXCEEDED); } - private String repeat(String str, int count) { - String result = ""; - for (int i = 0; i < count; i++) { - result += str; - } - return result; - } - // mixing operators @Test public void testMixingOperators01() { @@ -1373,6 +1379,15 @@ public List<Method> filter(List<Method> methods) { } + private static String repeat(String str, int count) { + String result = ""; + for (int i = 0; i < count; i++) { + result += str; + } + return result; + } + + @SuppressWarnings("rawtypes") static class TestClass {
b73f5fcac225Limit SpEL expression length
3 files changed · +36 −3
spring-expression/src/main/java/org/springframework/expression/spel/SpelMessage.java+7 −3 modified@@ -268,15 +268,19 @@ public enum SpelMessage { /** @since 5.2.23 */ MAX_REPEATED_TEXT_SIZE_EXCEEDED(Kind.ERROR, 1076, - "Repeated text results in too many characters, exceeding the threshold of ''{0}''"), + "Repeated text is too long, exceeding the threshold of ''{0}'' characters"), /** @since 5.2.23 */ MAX_REGEX_LENGTH_EXCEEDED(Kind.ERROR, 1077, - "Regular expression contains too many characters, exceeding the threshold of ''{0}''"), + "Regular expression is too long, exceeding the threshold of ''{0}'' characters"), /** @since 5.2.24 */ MAX_CONCATENATED_STRING_LENGTH_EXCEEDED(Kind.ERROR, 1078, - "Concatenated string is too long, exceeding the threshold of ''{0}'' characters"); + "Concatenated string is too long, exceeding the threshold of ''{0}'' characters"), + + /** @since 5.2.24 */ + MAX_EXPRESSION_LENGTH_EXCEEDED(Kind.ERROR, 1079, + "SpEL expression is too long, exceeding the threshold of ''{0}'' characters"); private final Kind kind;
spring-expression/src/main/java/org/springframework/expression/spel/standard/InternalSpelExpressionParser.java+15 −0 modified@@ -29,6 +29,7 @@ import org.springframework.expression.ParserContext; import org.springframework.expression.common.TemplateAwareExpressionParser; import org.springframework.expression.spel.InternalParseException; +import org.springframework.expression.spel.SpelEvaluationException; import org.springframework.expression.spel.SpelMessage; import org.springframework.expression.spel.SpelParseException; import org.springframework.expression.spel.SpelParserConfiguration; @@ -92,6 +93,12 @@ class InternalSpelExpressionParser extends TemplateAwareExpressionParser { private static final Pattern VALID_QUALIFIED_ID_PATTERN = Pattern.compile("[\\p{L}\\p{N}_$]+"); + /** + * Maximum length permitted for a SpEL expression. + * @since 5.2.24 + */ + private static final int MAX_EXPRESSION_LENGTH = 10_000; + private final SpelParserConfiguration configuration; @@ -127,6 +134,8 @@ public InternalSpelExpressionParser(SpelParserConfiguration configuration) { protected SpelExpression doParseExpression(String expressionString, @Nullable ParserContext context) throws ParseException { + checkExpressionLength(expressionString); + try { this.expressionString = expressionString; Tokenizer tokenizer = new Tokenizer(expressionString); @@ -148,6 +157,12 @@ protected SpelExpression doParseExpression(String expressionString, @Nullable Pa } } + private void checkExpressionLength(String string) { + if (string.length() > MAX_EXPRESSION_LENGTH) { + throw new SpelEvaluationException(SpelMessage.MAX_EXPRESSION_LENGTH_EXCEEDED, MAX_EXPRESSION_LENGTH); + } + } + // expression // : logicalOrExpression // ( (ASSIGN^ logicalOrExpression)
spring-expression/src/test/java/org/springframework/expression/spel/EvaluationTests.java+14 −0 modified@@ -60,6 +60,20 @@ class EvaluationTests extends AbstractExpressionTests { @Nested class MiscellaneousTests { + @Test + void expressionLength() { + String expression = "'X' + '%s'".formatted(" ".repeat(9_992)); + assertThat(expression).hasSize(10_000); + Expression expr = parser.parseExpression(expression); + String result = expr.getValue(context, String.class); + assertThat(result).hasSize(9_993); + assertThat(result.trim()).isEqualTo("X"); + + expression = "'X' + '%s'".formatted(" ".repeat(9_993)); + assertThat(expression).hasSize(10_001); + evaluateAndCheckError(expression, String.class, SpelMessage.MAX_EXPRESSION_LENGTH_EXCEEDED); + } + @Test void createListsOnAttemptToIndexNull01() throws EvaluationException, ParseException { ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
Vulnerability mechanics
Generated 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-wxqc-pxw9-g2p8ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2023-20863ghsaADVISORY
- github.com/spring-projects/spring-framework/commit/965a6392757d20f9db19241126fcc719a51eac15ghsaWEB
- github.com/spring-projects/spring-framework/commit/b73f5fcac22555f844cf27a7eeb876cb9d7f7f7eghsaWEB
- github.com/spring-projects/spring-framework/commit/ebc82654282bda547fbc20a9749ab1bda886a46fghsaWEB
- security.netapp.com/advisory/ntap-20240524-0015ghsaWEB
- spring.io/security/cve-2023-20863ghsaWEB
- security.netapp.com/advisory/ntap-20240524-0015/mitre
News mentions
0No linked articles in our index yet.