VYPR
High severity8.8NVD Advisory· Published Apr 12, 2016· Updated May 6, 2026

CVE-2016-0785

CVE-2016-0785

Description

Apache Struts 2.x before 2.3.28 allows remote attackers to execute arbitrary code via a "%{}" sequence in a tag attribute, aka forced double OGNL evaluation.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
org.apache.struts:struts2-coreMaven
>= 2.0.0, < 2.3.20.32.3.20.3
org.apache.struts:struts2-coreMaven
>= 2.3.24, < 2.3.24.32.3.24.3

Patches

1
15857a69e7ba

Reduces expression evaluation if there is no expression

https://github.com/apache/strutsLukasz LenartMar 6, 2016via ghsa
4 files changed · +56 5
  • core/src/main/java/org/apache/struts2/components/Component.java+5 1 modified
    @@ -373,7 +373,11 @@ protected Object findValue(String expr, String field, String errorMsg) {
          */
         protected Object findValue(String expr, Class toType) {
             if (altSyntax() && toType == String.class) {
    -        	return TextParseUtil.translateVariables('%', expr, stack);
    +            if (ComponentUtils.containsExpression(expr)) {
    +                return TextParseUtil.translateVariables('%', expr, stack);
    +            } else {
    +                return expr;
    +            }
             } else {
                 expr = stripExpressionIfAltSyntax(expr);
     
    
  • core/src/main/java/org/apache/struts2/util/ComponentUtils.java+6 3 modified
    @@ -40,12 +40,15 @@ public static boolean altSyntax(ValueStack stack) {
         /**
    
          * Check if object is expression base on altSyntax
    
          *
    
    -     * @param value to treat as an expression
    
    +     * @param expr to treat as an expression
    
          * @return true if it is an expression
    
          */
    
    -    public static boolean isExpression(Object value) {
    
    -        String expr = value.toString();
    
    +    public static boolean isExpression(String expr) {
    
             return expr.startsWith("%{") && expr.endsWith("}");
    
         }
    
     
    
    +    public static boolean containsExpression(String expr) {
    
    +        return expr.contains("%{") && expr.contains("}");
    
    +    }
    
    +
    
     }
    
    
  • core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractUITag.java+1 1 modified
    @@ -306,7 +306,7 @@ public void setLabelSeparator(String labelSeparator) {
         }
     
         public void setDynamicAttribute(String uri, String localName, Object value) throws JspException {
    -        if (ComponentUtils.altSyntax(getStack()) && ComponentUtils.isExpression(value)) {
    +        if (ComponentUtils.altSyntax(getStack()) && ComponentUtils.isExpression(value.toString())) {
                 dynamicAttributes.put(localName, String.valueOf(ObjectUtils.defaultIfNull(findValue(value.toString()), value)));
             } else {
                 dynamicAttributes.put(localName, value);
    
  • core/src/test/java/org/apache/struts2/util/ComponentUtilsTest.java+44 0 modified
    @@ -71,6 +71,17 @@ public void testIsExpressionIsTrue() throws Exception {
             assertTrue(actual);
    
         }
    
     
    
    +    public void testIsExpressionIsFalseWhenCombined() throws Exception {
    
    +        // given
    
    +        String anExpression = "bar%{foo}";
    
    +
    
    +        // when
    
    +        boolean actual = ComponentUtils.isExpression(anExpression);
    
    +
    
    +        // then
    
    +        assertFalse(actual);
    
    +    }
    
    +
    
         public void testIsExpressionIsFalse() throws Exception {
    
             // given
    
             String anExpression = "foo";
    
    @@ -81,6 +92,39 @@ public void testIsExpressionIsFalse() throws Exception {
             // then
    
             assertFalse(actual);
    
         }
    
    +
    
    +    public void testContainsExpressionIsTrue() throws Exception {
    
    +        // given
    
    +        String anExpression = "%{foo}";
    
    +
    
    +        // when
    
    +        boolean actual = ComponentUtils.containsExpression(anExpression);
    
    +
    
    +        // then
    
    +        assertTrue(actual);
    
    +    }
    
    +
    
    +    public void testIsContainsIsTrueWhenCombined() throws Exception {
    
    +        // given
    
    +        String anExpression = "bar%{foo}";
    
    +
    
    +        // when
    
    +        boolean actual = ComponentUtils.containsExpression(anExpression);
    
    +
    
    +        // then
    
    +        assertTrue(actual);
    
    +    }
    
    +
    
    +    public void testContainsExpressionIsFalse() throws Exception {
    
    +        // given
    
    +        String anExpression = "foo";
    
    +
    
    +        // when
    
    +        boolean actual = ComponentUtils.containsExpression(anExpression);
    
    +
    
    +        // then
    
    +        assertFalse(actual);
    
    +    }
    
     }
    
     
    
     class MockConfigurationProvider implements ConfigurationProvider {
    
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

8

News mentions

0

No linked articles in our index yet.