Security context
HighGHSA-wv88-pf73-x22p CVE-2011-2730Published May 17, 2022

Improper Neutralization of Directives in Dynamically Evaluated Code in Spring Framework

Research this vulnerability

Research is free — Hunters explains how the bug works, the root-cause code pattern, how the fix addresses it, and how to test whether a target is affected, in chat. Investigate & write exploit is a paid run — the engine reads the advisory and fix commits, then builds and validates a working proof-of-concept exploit with reproduction steps.

Affected versions

3.0.0 → fixed in 3.0.60 → fixed in 2.5.6.SEC032.5.7.SR0 → fixed in 2.5.7.SR023

Details

VMware SpringSource Spring Framework before 2.5.6.SEC03, 2.5.7.SR023, and 3.x before 3.0.6, when a container supports Expression Language (EL), evaluates EL expressions in tags twice, which allows remote attackers to obtain sensitive information via a (1) name attribute in a (a) spring:hasBindErrors tag; (2) path attribute in a (b) spring:bind or (c) spring:nestedpath tag; (3) arguments, (4) code, (5) text, (6) var, (7) scope, or (8) message attribute in a (d) spring:message or (e) spring:theme tag; or (9) var, (10) scope, or (11) value attribute in a (f) spring:transform tag, aka "Expression Language Injection."

The fix

Deprecated Spring's own JSP expression evaluation

Juergen Hoeller· Nov 25, 2012, 11:15 PM+331262ccc8dd7e
spring-web/src/test/java/org/springframework/web/util/ExpressionEvaluationUtilsTests.java+33 12
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2011 the original author or authors.
+ * Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
package org.springframework.web.util;
+import javax.servlet.ServletContext;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.el.ELException;
@@ -33,7 +34,7 @@
import static org.junit.Assert.*;
/**
- * @author Aled Arendsen
+ * @author Alef Arendsen
* @author Juergen Hoeller
* @since 16.09.2003
*/
@@ -43,9 +44,9 @@ public class ExpressionEvaluationUtilsTests {
public void testIsSpringJspExpressionSupportActive() {
MockServletContext sc = new MockServletContext();
PageContext pc = new MockPageContext(sc);
- assertTrue(ExpressionEvaluationUtils.isSpringJspExpressionSupportActive(pc));
- sc.addInitParameter("springJspExpressionSupport", "false");
assertFalse(ExpressionEvaluationUtils.isSpringJspExpressionSupportActive(pc));
+ sc.addInitParameter("springJspExpressionSupport", "true");
+ assertTrue(ExpressionEvaluationUtils.isSpringJspExpressionSupportActive(pc));
}
@Test
@@ -82,7 +83,9 @@ public void testIsExpressionLanguage() {
@Test
public void testEvaluate() throws Exception {
- PageContext ctx = new MockPageContext();
+ MockServletContext sc = new MockServletContext();
+ sc.addInitParameter("springJspExpressionSupport", "true");
+ MockPageContext ctx = new MockPageContext(sc);
ctx.setAttribute("bla", "blie");
assertEquals("blie", ExpressionEvaluationUtils.evaluate("test", "${bla}", String.class, ctx));
@@ -99,7 +102,9 @@ public void testEvaluate() throws Exception {
@Test
public void testEvaluateWithConcatenation() throws Exception {
- PageContext ctx = new MockPageContext();
+ MockServletContext sc = new MockServletContext();
+ sc.addInitParameter("springJspExpressionSupport", "true");
+ MockPageContext ctx = new MockPageContext(sc);
ctx.setAttribute("bla", "blie");
String expr = "text${bla}text${bla}text";
@@ -139,7 +144,9 @@ public void testEvaluateWithConcatenation() throws Exception {
@Test
public void testEvaluateString() throws Exception {
- PageContext ctx = new MockPageContext();
+ MockServletContext sc = new MockServletContext();
+ sc.addInitParameter("springJspExpressionSupport", "true");
+ MockPageContext ctx = new MockPageContext(sc);
ctx.setAttribute("bla", "blie");
assertEquals("blie", ExpressionEvaluationUtils.evaluateString("test", "${bla}", ctx));
@@ -148,7 +155,9 @@ public void testEvaluateString() throws Exception {
@Test
public void testEvaluateStringWithConcatenation() throws Exception {
- PageContext ctx = new MockPageContext();
+ MockServletContext sc = new MockServletContext();
+ sc.addInitParameter("springJspExpressionSupport", "true");
+ MockPageContext ctx = new MockPageContext(sc);
ctx.setAttribute("bla", "blie");
String expr = "text${bla}text${bla}text";
@@ -180,7 +189,9 @@ public void testEvaluateStringWithConcatenation() throws Exception {
@Test
public void testEvaluateInteger() throws Exception {
- PageContext ctx = new MockPageContext();
+ MockServletContext sc = new MockServletContext();
+ sc.addInitParameter("springJspExpressionSupport", "true");
+ MockPageContext ctx = new MockPageContext(sc);
ctx.setAttribute("bla", new Integer(1));
assertEquals(1, ExpressionEvaluationUtils.evaluateInteger("test", "${bla}", ctx));
@@ -189,7 +200,9 @@ public void testEvaluateInteger() throws Exception {
@Test
public void testEvaluateBoolean() throws Exception {
- PageContext ctx = new MockPageContext();
+ MockServletContext sc = new MockServletContext();
+ sc.addInitParameter("springJspExpressionSupport", "true");
+ MockPageContext ctx = new MockPageContext(sc);
ctx.setAttribute("bla", new Boolean(true));
assertTrue(ExpressionEvaluationUtils.evaluateBoolean("test", "${bla}", ctx));
@@ -198,7 +211,9 @@ public void testEvaluateBoolean() throws Exception {
@Test
public void testRepeatedEvaluate() throws Exception {
- PageContext ctx = new CountingMockPageContext();
+ MockServletContext sc = new MockServletContext();
+ sc.addInitParameter("springJspExpressionSupport", "true");
+ PageContext ctx = new CountingMockPageContext(sc);
CountingMockExpressionEvaluator eval = (CountingMockExpressionEvaluator) ctx.getExpressionEvaluator();
ctx.setAttribute("bla", "blie");
ctx.setAttribute("blo", "blue");
@@ -218,7 +233,9 @@ public void testRepeatedEvaluate() throws Exception {
@Test
public void testEvaluateWithComplexConcatenation() throws Exception {
- PageContext ctx = new CountingMockPageContext();
+ MockServletContext sc = new MockServletContext();
+ sc.addInitParameter("springJspExpressionSupport", "true");
+ PageContext ctx = new CountingMockPageContext(sc);
CountingMockExpressionEvaluator eval = (CountingMockExpressionEvaluator) ctx.getExpressionEvaluator();
ctx.setAttribute("bla", "blie");
ctx.setAttribute("blo", "blue");
@@ -247,6 +264,10 @@ public void testEvaluateWithComplexConcatenation() throws Exception {
private static class CountingMockPageContext extends MockPageContext {
+ public CountingMockPageContext(ServletContext servletContext) {
+ super(servletContext);
+ }
+
private ExpressionEvaluator eval = new CountingMockExpressionEvaluator(this);
public ExpressionEvaluator getExpressionEvaluator() {

Deprecated Spring's own JSP expression evaluation

Juergen Hoeller· Nov 25, 2012, 07:50 PM+12139772eb8410
spring-web/src/main/java/org/springframework/web/util/ExpressionEvaluationUtils.java+12 13
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2011 the original author or authors.
+ * Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -39,7 +39,10 @@
* @author Alef Arendsen
* @since 11.07.2003
* @see javax.servlet.jsp.el.ExpressionEvaluator#evaluate
+ * @deprecated as of Spring 3.2, in favor of the JSP 2.0+ native support
+ * for embedded expressions in JSP pages (also applying to tag attributes)
*/
+@Deprecated
public abstract class ExpressionEvaluationUtils {
/**
@@ -64,13 +67,9 @@ public abstract class ExpressionEvaluationUtils {
* containers with web applications declaring Servlet 2.4 or higher in their
* <code>web.xml</code>. For backwards compatibility, Spring's expression support
* will remain active for applications declaring Servlet 2.3 or earlier. However,
- * on Servlet 2.4/2.5 containers, we can't find out what the application has declared,
- * so we'll also fall back to keeping expression support active in such a case.
- * <p><b>Recommendations:</b> Explicitly set "springJspExpressionSupport" to "false"
- * in order to prevent double evaluation for Servlet 2.4+ based applications.
- * On Servlet 3.0 containers, this will be done for you by default by the framework.
- * If for some reason you nevertheless want Spring's JSP expression support to be
- * active, explicitly set the "springJspExpressionSupport" context-param to "true".
+ * on Servlet 2.4/2.5 containers, we can't find out what the application has declared;
+ * as of Spring 3.2, we won't activate Spring's expression support at all then since
+ * it got deprecated and will be removed in the next iteration of the framework.
* @param pageContext current JSP PageContext
* @return <code>true</code> if active (ExpressionEvaluationUtils will actually evaluate expressions);
* <code>false</code> if not active (ExpressionEvaluationUtils will return given values as-is,
@@ -84,13 +83,13 @@ public static boolean isSpringJspExpressionSupportActive(PageContext pageContext
}
if (sc.getMajorVersion() >= 3) {
// We're on a Servlet 3.0+ container: Let's check what the application declares...
- if (sc.getEffectiveMajorVersion() > 2 || sc.getEffectiveMinorVersion() > 3) {
- // Application declares Servlet 2.4+ in its web.xml: JSP 2.0 expressions active.
- // Skip our own expression support in order to prevent double evaluation.
- return false;
+ if (sc.getEffectiveMajorVersion() == 2 && sc.getEffectiveMinorVersion() < 4) {
+ // Application declares Servlet 2.3- in its web.xml: JSP 2.0 expressions not active.
+ // Activate our own expression support.
+ return true;
}
}
- return true;
+ return false;
}
/**

Deprecated Spring's own JSP expression evaluation

Juergen Hoeller· Nov 25, 2012, 11:35 PM+10b8d86330d1
spring-webmvc/src/test/java/org/springframework/web/servlet/tags/AbstractTagTests.java+1 0
@@ -41,6 +41,7 @@ public abstract class AbstractTagTests extends TestCase {
protected MockPageContext createPageContext() {
MockServletContext sc = new MockServletContext();
+ sc.addInitParameter("springJspExpressionSupport", "true");
SimpleWebApplicationContext wac = new SimpleWebApplicationContext();
wac.setServletContext(sc);
wac.setNamespace("test");

References