Overview
Spring is a Java framework typically used for enterprise and web applications, though it can be used for desktop applications, as well. It is composed of many modules and not all modules are used by every deployment.
This vulnerability (CVE-2023-20863) is in the spring-expression library, which is responsible for evaluating Spring Expression Language (SpEL) expressions. It allows for denial of service (DoS) via excessive recursion when processing expressions, particularly those using the repeat operator (*) and concatenation operator (+) to create very large expressions, leading to an OutOfMemoryError.
The Open Web Application Security Project (OWASP) explains that denial of service (DoS) attacks aim to make a service “unavailable for the purpose it was designed.” In this case, the vulnerability allows susceptible SpEL expressions to use most system resources and deny other users access to the system.
This issue affects multiple versions of spring-expression form Spring Framework.
Details
Module Info
- Product: Spring Framework
- Affected packages: spring-expression
- Affected versions: <5.2.24, >=5.3.0 <5.3.27, >=6.0.0 <6.0.8
- 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 v4.3.32 and v5.3.44
Vulnerability Info
This Medium-severity vulnerability is found in the spring-expression.jar module of the Spring Framework.
When user-supplied Spring Expression Language (SpEL) expressions with repetition are evaluated, it is possible to exhaust system resources. Sending a specially crafted SpEL expression to the application where it would attempt to concatenate large strings many times exhibits the flaw. For instance, an expression like “'A' * 100000000 + ‘B’ * 100000000” + ‘C’ * 100000000” would try to create a string of 100,000,000 'A's followed by 100,000,000 ‘B’s and 100,000,000 ‘C’s. In environments where string creation is not optimized or limited, this could lead to an OutOfMemoryError as the application tries to allocate memory for such an enormous string.
Consider the following mitigation options if upgrading to a corrected version of the library is not immediately available:
- Restrict SpEL Permissions and Operators: Use SimpleEvaluationContext.forReadOnlyDataBinding() as it prevents use of the repetition operator (*) that enables this vulnerability. If you need more complex expression evaluation, use StandardEvaluationContext with custom PropertyAccessor and MethodResolver implementations to whitelist only required functionality. Note that StandardEvaluationContext alone will not prevent the repetition operator vulnerability.
- Sanitize Input: For applications that need to process some dynamic expressions, adding pre-validation steps to sanitize input can prevent malicious or unexpected constructs from reaching the evaluation stage.
- Monitor Resource Usage: For applications particularly vulnerable to DoS, monitoring and alerting on CPU and memory usage can help detect unusual spikes, allowing you to respond to potential attacks swiftly.
Steps To Reproduce
To reproduce this vulnerability in a controlled environment, you would need a Spring application running an affected version and an available end point.
1. Set up a vulnerable Spring application:
- Create a simple Spring Boot application using a vulnerable Spring Framework version, such as 5.3.26
2. Add additional files to fill out the project. Launch the app with a limited amount of memory by including a memory parameter such as -Xmx512m
3. Craft a malicious request that employs repetition similar to the one below:
'A' * 100000000 + 'B' * 100000000 + 'C' * 100000000
4. Send the request to an end-point in the application, such as the one defined below:
@RestController
public class ExpressionController {
@PostMapping("/evaluate")
public ResponseEntity<String> evaluateExpression(@RequestBody String expression) {
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression(expression);
String result = exp.getValue(String.class);
return ResponseEntity.ok(result);
}
}
5. Send the request to an end-point in the application using a tool such as curl or Postman:
curl -X POST \
-H "Content-Type: text/plain" \
-d "'A' * 100000000 + 'B' * 100000000 + 'C' * 100000000" \
http://localhost:8080/evaluate
6. Observe the impact:
- Monitor the server's CPU, memory, and disk usage with monitoring tools. The denial-of-service (DoS) impact should be noticeable as the server executes the expression.
- Server logs may also show system degradation.
Credits
- Code Intelligence
Mitigation
Spring Framework 4 and 5 are no longer community-supported. The community support version will not receive any updates to address this issue. For more information, see here.
Users of the affected components should apply one of the following mitigations:
- Upgrade to a corrected version
- Leverage a commercial support partner like HeroDevs for post-EOL security support.
- A partial workaround is to avoid using user-supplied expressions or to configure SimpleEvaluationContext with forReadOnlyDataBinding() to prevent use of the repetition operator.