SpEL Injection
Last updated
Last updated
The Spring Expression Language (SpEL for short) is a powerful expression language that supports querying and manipulating an object graph at runtime.
The following code introduces the SpEL API to evaluate the literal string expression Hello World!
:
The value of the message
variable is simply Hello World!
.
The interface EvaluationContext is used when evaluating an expression to resolve properties, methods, fields, and to help perform type conversion. There are two main out-of-the-box implementations:
StandardEvaluationContext. A powerful and highly configurable EvaluationContext
implementation. This context uses standard implementations of all applicable strategies, based on reflection to resolve properties, methods and fields.
SimpleEvaluationContext. A basic implementation of EvaluationContext
that focuses on a subset of essential SpEL features and customization options, targeting simple condition evaluation and in particular data binding scenarios.
SpEL expressions can be used with XML or annotation based configuration metadata for defining BeanDefinitions. In both cases the syntax to define the expression is of the form #{ <expression string> }
.
You can set a property or constructor-arg value using expressions.
The @Value
annotation can be placed on fields, methods and method/constructor parameters to specify a default value.
SpEL injection occurs when user controlled data is passed directly to the SpEL expression parser. For instance, the following method uses the standard context to evaluate SpEL expression:
As a result, you can gain code execution by sending the following POST
request:
If you have access to a source code, try to search for vulnerable code using the following keywords:
SpelExpressionParser
, EvaluationContext
, parseExpression
, @Value("#{ <expression string> }")
#{ <expression string> }
, ${<property>}
, T(<javaclass>)
If a source code is not available, it is worth checking the metrics
and beans
endpoints provided by the Spring Boot actuators. These endpoints can expand the list of available beans and the parameters they accept.
Additionally, try to use expressions in different elements of the service:
Parameter names and values:
variable[<expression string>]=123
variable=123&<expression string>=123
{"<expression string>":"123"}
{"variable":"<expression string>"}
HTTP headers:
Cookie: cookie_name=<expression string>
Cookie: <expression string>=cookie_value
Private-Token: <expression string>
etc.
You can use the following payloads as the expression string:
This vulnerability requires the following conditions:
Spring Boot version 1.1.0 - 1.1.12
, 1.2.0 - 1.2.7
, 1.3.0
There is at least one interface that triggers the default whitelabel error page in Spring Boot
Check the next Spring Boot application: LandGrey/springboot-spel-rce. If you send a request to /article?id=hop
, the application will return a whitelabel error with code 500
. However, if you send a request to /article?id=${7*7}
, the application returns an error page with the calculated value 49
. It happens because:
Spring Boot processes URL parameters in errors with the org.springframework.util.PropertyPlaceholderHelper
class
PropertyPlaceholderHelper.parseStringValue
method parses URL parameters
Content enclosed in ${}
will be parsed and executed as a SpEL expression by the resolvePlaceholder
method of org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration
class
As a result, it leads to RCE and you can execute arbitrary commands using the following steps:
Prepare the payload with the next python scrypt (this sample prepares a payload that executes open -a Calculator
command):
Send the payload within the id
parameter:
open -a Calculator
will be executed
References:
The SimpleEvaluationContext
context prevents arbitrary code executing and writes a error message. However, you still can exploit the ReDoS attack.