diff --git a/framework-docs/modules/ROOT/pages/core/expressions/evaluation.adoc b/framework-docs/modules/ROOT/pages/core/expressions/evaluation.adoc index 6f18e635436..e7bee3b66b6 100644 --- a/framework-docs/modules/ROOT/pages/core/expressions/evaluation.adoc +++ b/framework-docs/modules/ROOT/pages/core/expressions/evaluation.adoc @@ -253,6 +253,39 @@ properties. Alternatively, configure custom accessors via `SimpleEvaluationContext.forPropertyAccessors(...)`, potentially disable assignment, and optionally activate method resolution and/or a type converter through the builder. +[[expressions-evaluation-context-security]] +=== Security Considerations + +SpEL is a powerful expression language that can invoke constructors and methods, read and +write properties and fields, and reference beans – all backed by reflection. Because of +this power, evaluating a SpEL expression obtained from an untrusted source is inherently +dangerous and should generally be avoided, since doing so can effectively grant that +source the ability to execute arbitrary code within the application, regardless of which +`EvaluationContext` implementation is used. + +Throughout this section, a source is considered "trusted" only if it is a developer of +the application or an administrator responsible for configuring or operating the +application. Any other source of a SpEL expression must be treated as untrusted – for +example, an expression supplied by an end user of the application or received from an +external system. + +[WARNING] +==== +`StandardEvaluationContext` exposes the complete SpEL language and must *never* be used +to evaluate an expression obtained from an untrusted source. +==== + +Although `SimpleEvaluationContext` restricts the SpEL language to a subset of its +features, that restriction is provided on a best-effort basis and does not guarantee that +expression evaluation is safe. Since an expression can potentially invoke any property, +method, or function reachable via the configured root object, property accessors, method +resolvers, variables, and functions, care must be taken if you choose to evaluate +expressions from an untrusted source. It is therefore the responsibility of the code that +configures an `EvaluationContext` – for example, by supplying a root object or by +registering property accessors, resolvers, variables, or functions – to ensure that none +of the objects reachable via the context expose operations that would be dangerous if +invoked by an expression from an untrusted source. + [[expressions-type-conversion]] === Type Conversion diff --git a/spring-expression/src/main/java/org/springframework/expression/EvaluationContext.java b/spring-expression/src/main/java/org/springframework/expression/EvaluationContext.java index c9b55f29a8c..3e807bdac53 100644 --- a/spring-expression/src/main/java/org/springframework/expression/EvaluationContext.java +++ b/spring-expression/src/main/java/org/springframework/expression/EvaluationContext.java @@ -38,6 +38,24 @@ import org.jspecify.annotations.Nullable; * manually. * * + *
WARNING: Evaluating a SpEL expression obtained from an + * untrusted source is inherently dangerous, since doing so can effectively + * grant that source the ability to execute arbitrary code within the + * application. See the class-level documentation for + * {@code StandardEvaluationContext} and {@code SimpleEvaluationContext} for + * details on the trust model applicable to each implementation. Regardless of + * which {@code EvaluationContext} implementation is in use, any restrictions + * that an implementation imposes on the SpEL language are provided on a + * best-effort basis and do not, by themselves, guarantee that expression + * evaluation is safe. An expression can potentially invoke any property, method, + * or function reachable via the configured root object, property accessors, + * index accessors, resolvers, variables, and functions. It is therefore the + * responsibility of the code that configures an {@code EvaluationContext} + * — for example, by supplying a root object or by registering property + * accessors, resolvers, variables, or functions — to ensure that none of + * those reachable objects expose operations that would be dangerous if invoked + * by an expression from an untrusted source. + * * @author Andy Clement * @author Juergen Hoeller * @author Sam Brannen diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/support/SimpleEvaluationContext.java b/spring-expression/src/main/java/org/springframework/expression/spel/support/SimpleEvaluationContext.java index e18599bab91..1e6931daa4c 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/support/SimpleEvaluationContext.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/support/SimpleEvaluationContext.java @@ -49,8 +49,8 @@ import org.springframework.expression.spel.SpelMessage; * should be meaningfully restricted. Examples include but are not limited to * data binding expressions, property-based filters, and others. To that effect, * {@code SimpleEvaluationContext} is tailored to support only a subset of the - * SpEL language syntax, for example, excluding references to Java types, constructors, - * and bean references. + * SpEL language syntax — for example, excluding references to Java types, + * constructors, and bean references. * *
When creating a {@code SimpleEvaluationContext} you need to choose the level of * support that you need for data binding in SpEL expressions: @@ -65,9 +65,10 @@ import org.springframework.expression.spel.SpelMessage; * read-only access to properties via {@link DataBindingPropertyAccessor}. Similarly, * {@link SimpleEvaluationContext#forReadWriteDataBinding()} enables read and write access * to properties. Alternatively, configure custom accessors via - * {@link SimpleEvaluationContext#forPropertyAccessors}, potentially - * {@linkplain Builder#withAssignmentDisabled() disable assignment}, and optionally - * activate method resolution and/or a type converter through the builder. + * {@link SimpleEvaluationContext#forPropertyAccessors}, consider + * {@linkplain Builder#withAssignmentDisabled() disabling assignment} (recommended), + * and optionally activate method resolution and/or a type converter through the + * builder. * *
Note that {@code SimpleEvaluationContext} is typically not configured * with a default root object. Instead it is meant to be created once and @@ -87,6 +88,23 @@ import org.springframework.expression.spel.SpelMessage; *
For more power and flexibility, in particular for internal configuration * scenarios, consider using {@link StandardEvaluationContext} instead. * + *
WARNING: {@code SimpleEvaluationContext} takes a + * best-effort approach to restricting the SpEL language to a subset of its + * features; however, it cannot guarantee that evaluation of an expression is + * safe. Evaluating a SpEL expression obtained from an untrusted source is inherently + * dangerous and should generally be avoided, since doing so can effectively grant + * that source the ability to execute arbitrary code within the application. Even + * within the restricted language subset supported by {@code SimpleEvaluationContext}, + * an expression can potentially invoke any property, method, or function reachable + * via the configured root object, property accessors, method resolvers, variables, + * and functions. It is therefore the responsibility of the code that configures a + * {@code SimpleEvaluationContext} — for example, by supplying a root + * object or by registering property accessors, method resolvers, variables, or + * functions — to ensure that none of those reachable objects expose + * operations that would be dangerous if invoked by an expression from an + * untrusted source. For details on what qualifies as a "trusted" source, see + * {@link StandardEvaluationContext}. + * * @author Rossen Stoyanchev * @author Juergen Hoeller * @author Sam Brannen diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardEvaluationContext.java b/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardEvaluationContext.java index 721d4380462..01155813b3e 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardEvaluationContext.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardEvaluationContext.java @@ -64,6 +64,22 @@ import org.springframework.util.Assert; * consider using {@link SimpleEvaluationContext} instead which allows for * opting into several SpEL features as needed by specific use cases. * + *
WARNING: {@code StandardEvaluationContext} exposes the + * complete SpEL language, including the ability to invoke arbitrary constructors + * and methods and to read and write arbitrary properties and fields — all + * backed by reflection — as well as the ability to reference beans in an + * {@code ApplicationContext} via a configured {@link BeanResolver}. For that + * reason, a {@code StandardEvaluationContext} must never be used + * to evaluate a SpEL expression obtained from an untrusted source. In this context, + * a "trusted" source is limited to a developer of the application or an + * administrator who is responsible for configuring or operating the + * application. Any other source of a SpEL expression — for example, an + * expression supplied by an end user or received from an external system + * — must be treated as untrusted. Note, however, that evaluating a SpEL + * expression obtained from an untrusted source is inherently dangerous + * regardless of the {@code EvaluationContext} implementation in use; see + * {@link SimpleEvaluationContext} for further details. + * * @author Andy Clement * @author Juergen Hoeller * @author Sam Brannen