CVE-2026-41849
This Vulnerability has been fixed in the Never-Ending Support (NES) version offered by HeroDevs.
Overview
Spring Framework is the foundational application framework for the Java platform, providing dependency injection, data access, web, and expression-evaluation support to a large share of enterprise Java applications. One of its modules, spring-expression, implements the Spring Expression Language (SpEL): a runtime expression language that can query and manipulate object graphs, and that many applications evaluate against application-defined or, in some designs, externally-influenced input.
A high-severity vulnerability (CVE-2026-41849) has been identified in the SpEL evaluation logic. The SpEL multiply operator doubles as a string-repeat operator (multiplying a string by an integer repeats it). On the affected line, the size of the repeated text is computed with a 32-bit int multiplication before being checked against a fixed maximum, and the bounds check does not account for integer overflow. A crafted expression whose length-times-count product overflows the int range wraps to a negative or small value, slips past the size check, and then drives either an immediate failure or unbounded memory and CPU consumption, resulting in a Denial of Service.
Per OWASP, an integer overflow occurs when an arithmetic operation attempts to create a numeric value that is outside of the range that can be represented with a given number of bytes; when this occurs, the value may wrap to become a very small or negative number. Here the overflow of the repeated-text size calculation defeats a guard whose entire purpose is to bound resource usage, turning a single short expression into a resource-exhaustion vector.
This vulnerability only matters where an application evaluates attacker-influenced SpEL. Applications that never expose SpEL evaluation to untrusted input are not exposed through this path. This issue affects >=5.3.0 <=5.3.48 of Spring Framework.
Details
Module Info
- Product: Spring Framework
- Affected packages: spring-expression
- Affected versions: >=5.3.0 <=5.3.48
- GitHub repository: https://github.com/spring-projects/spring-framework
- Published packages: https://central.sonatype.com/artifact/org.springframework/spring-expression
- Package manager: Maven
- Fixed in:
- NES for Spring Framework 4.3.x, 5.3.x
Vulnerability Info
The vulnerability is in OpMultiply in the spring-expression module, specifically in the getValueInternal(ExpressionState) method that evaluates the multiply operator. When the left operand is a String and the right operand is an Integer, the operator performs string repetition. To bound output, the operator caps repeated text at MAX_REPEATED_TEXT_SIZE, which is 256 characters.
On the affected 5.3.x line, the requested size is computed and checked like this:
if (leftOperand instanceof String && rightOperand instanceof Integer) {
String text = (String) leftOperand;
int count = (Integer) rightOperand;
int requestedSize = text.length() * count;
checkRepeatedTextSize(requestedSize);
StringBuilder result = new StringBuilder(requestedSize);
for (int i = 0; i < count; i++) {
result.append(text);
}
return new TypedValue(result.toString());
}
private void checkRepeatedTextSize(int requestedSize) {
if (requestedSize > MAX_REPEATED_TEXT_SIZE) {
throw new SpelEvaluationException(getStartPosition(),
SpelMessage.MAX_REPEATED_TEXT_SIZE_EXCEEDED, MAX_REPEATED_TEXT_SIZE);
}
}
The product text.length() * count is a plain int multiplication. When that product exceeds Integer.MAX_VALUE it wraps negative. checkRepeatedTextSize only rejects values strictly greater than 256, so a wrapped value that is negative or small passes the guard. Two failure modes follow. If requestedSize wraps negative, new StringBuilder(requestedSize) is constructed with a negative capacity and throws NegativeArraySizeException, which is an unchecked RuntimeException. If the wrapped value is less than 256 but non-negative, the guard is satisfied, yet the loop still iterates count times, where count is a very large positive number, appending text on each iteration and driving the heap and CPU toward exhaustion until the JVM throws OutOfMemoryError. Either way, a single short expression chosen so that length-times-count overflows can result in a denial of service for the evaluating thread or process.
The corrected behavior computes the repeated-text size with overflow detection rather than a wrapping int multiplication. Equivalent to the guard already present on later Spring Framework lines (which reject a result that is negative as well as one that exceeds the maximum), the fix computes the size with Math.multiplyExact and translates the overflow into the existing size-exceeded error:
int requestedSize = computeRepeatedTextSize(text, count);
checkRepeatedTextSize(requestedSize);
private int computeRepeatedTextSize(String text, int count) {
try {
return Math.multiplyExact(text.length(), count);
}
catch (ArithmeticException ex) {
throw new SpelEvaluationException(getStartPosition(),
SpelMessage.MAX_REPEATED_TEXT_SIZE_EXCEEDED, MAX_REPEATED_TEXT_SIZE);
}
}
With this change an overflowing product can no longer wrap past the size check; it is detected and rejected with a SpelEvaluationException carrying MAX_REPEATED_TEXT_SIZE_EXCEEDED, exactly as an oversized-but-non-overflowing request already is. The control flow and the public API of OpMultiply are otherwise unchanged. Spring Framework lines 6.1.x and later are not affected by this issue: their repeat guard already rejects a negative result, so an integer-overflow wrap cannot bypass the check.
Mitigation
Spring Framework 4.3.x and 5.3.x are past their open-source support window, and there are no open-source 4.3.x or 5.3.x releases that contain the fix.
Users of the affected component should apply one of the following mitigations:
- Upgrade to a currently supported version of Spring Framework.
- Where evaluating attacker-influenced SpEL is not required, avoid passing untrusted input into SpEL evaluation, which removes the attack surface for this issue.
- Leverage a commercial support partner like HeroDevs for post-end-of-life security support through Never-Ending Support (NES) for Spring Framework, which provides a patched 4.3.x and 5.3.x build.
Credits
- This issue was discovered internally by the Spring team.