VYPR
High severityNVD Advisory· Published Jul 10, 2013· Updated Apr 29, 2026

CVE-2013-1965

CVE-2013-1965

Description

Apache Struts Showcase App 2.0.0 through 2.3.13, as used in Struts 2 before 2.3.14.3, allows remote attackers to execute arbitrary OGNL code via a crafted parameter name that is not properly handled when invoking a redirect.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
org.apache.struts:struts2-coreMaven
< 2.3.14.32.3.14.3

Affected products

2
  • cpe:2.3:a:apache:struts:*:*:*:*:*:*:*:*
    Range: >=2.0.0,<2.3.14.1
  • cpe:2.3:a:apache:struts2-showcase:*:*:*:*:*:*:*:*
    Range: >=2.0.0,<=2.3.13

Patches

1
7e6f641ebb14

Disable eval expressions

https://github.com/apache/strutsMaurizio CucchiaraApr 18, 2013via ghsa
6 files changed · +46 13
  • core/src/main/java/org/apache/struts2/config/BeanSelectionProvider.java+1 0 modified
    @@ -375,6 +375,7 @@ public void register(ContainerBuilder builder, LocatableProperties props) {
             // Convert Struts properties into XWork properties
             convertIfExist(props, StrutsConstants.STRUTS_LOG_MISSING_PROPERTIES, XWorkConstants.LOG_MISSING_PROPERTIES);
             convertIfExist(props, StrutsConstants.STRUTS_ENABLE_OGNL_EXPRESSION_CACHE, XWorkConstants.ENABLE_OGNL_EXPRESSION_CACHE);
    +        convertIfExist(props, StrutsConstants.STRUTS_ENABLE_OGNL_EVAL_EXPRESSION, XWorkConstants.ENABLE_OGNL_EVAL_EXPRESSION);
             convertIfExist(props, StrutsConstants.STRUTS_ALLOW_STATIC_METHOD_ACCESS, XWorkConstants.ALLOW_STATIC_METHOD_ACCESS);
             convertIfExist(props, StrutsConstants.STRUTS_CONFIGURATION_XML_RELOAD, XWorkConstants.RELOAD_XML_CONFIGURATION);
     
    
  • core/src/main/java/org/apache/struts2/StrutsConstants.java+3 0 modified
    @@ -228,6 +228,9 @@ public final class StrutsConstants {
         /** Enables caching of parsed OGNL expressions **/
         public static final String STRUTS_ENABLE_OGNL_EXPRESSION_CACHE = "struts.ognl.enableExpressionCache";
     
    +    /** Enables evaluation of OGNL expressions **/
    +    public static final String STRUTS_ENABLE_OGNL_EVAL_EXPRESSION = "struts.ognl.enableOGNLEvalExpression";
    +
         /** The{@link org.apache.struts2.views.util.UrlHelper} implementation class **/
         public static final String STRUTS_URL_HELPER = "struts.view.urlHelper";
     
    
  • xwork-core/src/main/java/com/opensymphony/xwork2/config/impl/DefaultConfiguration.java+1 0 modified
    @@ -319,6 +319,7 @@ protected Container createBootstrapContainer(List<ContainerProvider> providers)
             builder.factory(OgnlUtil.class, Scope.SINGLETON);
             builder.constant(XWorkConstants.DEV_MODE, "false");
             builder.constant(XWorkConstants.LOG_MISSING_PROPERTIES, "false");
    +        builder.constant(XWorkConstants.ENABLE_OGNL_EVAL_EXPRESSION, "false");
             builder.constant(XWorkConstants.RELOAD_XML_CONFIGURATION, "false");
             return builder.create(true);
         }
    
  • xwork-core/src/main/java/com/opensymphony/xwork2/config/providers/XWorkConfigurationProvider.java+1 0 modified
    @@ -151,6 +151,7 @@ public void register(ContainerBuilder builder, LocatableProperties props)
             props.setProperty(XWorkConstants.DEV_MODE, Boolean.FALSE.toString());
             props.setProperty(XWorkConstants.LOG_MISSING_PROPERTIES, Boolean.FALSE.toString());
             props.setProperty(XWorkConstants.ENABLE_OGNL_EXPRESSION_CACHE, Boolean.TRUE.toString());
    +        props.setProperty(XWorkConstants.ENABLE_OGNL_EVAL_EXPRESSION, Boolean.FALSE.toString());
             props.setProperty(XWorkConstants.RELOAD_XML_CONFIGURATION, Boolean.FALSE.toString());
         }
     
    
  • xwork-core/src/main/java/com/opensymphony/xwork2/ognl/OgnlUtil.java+39 13 modified
    @@ -56,6 +56,7 @@ public class OgnlUtil {
         private TypeConverter defaultConverter;
         static boolean devMode = false;
         static boolean enableExpressionCache = true;
    +    private static boolean enableEvalExpression;
     
         @Inject
         public void setXWorkConverter(XWorkConverter conv) {
    @@ -67,11 +68,20 @@ public static void setDevMode(String mode) {
             devMode = "true".equals(mode);
         }
     
    -    @Inject("enableOGNLExpressionCache")
    +    @Inject(XWorkConstants.ENABLE_OGNL_EXPRESSION_CACHE)
         public static void setEnableExpressionCache(String cache) {
            enableExpressionCache = "true".equals(cache);
         }
     
    +    @Inject(value = XWorkConstants.ENABLE_OGNL_EVAL_EXPRESSION, required = false)
    +    public void setEnableEvalExpression(String evalExpression) {
    +        enableEvalExpression = "true".equals(evalExpression);
    +        if(enableEvalExpression){
    +            LOG.warn("Enabling OGNL expression evaluation may introduce security risks " +
    +                    "(see http://struts.apache.org/release/2.3.x/docs/s2-013.html for further details)");
    +        }
    +    }
    +
         /**
          * Sets the object's properties using the default type converter, defaulting to not throw
          * exceptions for problems setting the properties.
    @@ -217,7 +227,7 @@ public void setValue(String name, Map<String, Object> context, Object root, Obje
         }
     
         protected void setValue(String name, Map<String, Object> context, Object root, Object value, boolean evalName) throws OgnlException {
    -        Object tree = compile(name);
    +        Object tree = compile(name, context);
             if (!evalName && isEvalExpression(tree, context)) {
                 throw new OgnlException("Eval expression cannot be used as parameter name");
             }
    @@ -227,30 +237,46 @@ protected void setValue(String name, Map<String, Object> context, Object root, O
         private boolean isEvalExpression(Object tree, Map<String, Object> context) throws OgnlException {
             if (tree instanceof SimpleNode) {
                 SimpleNode node = (SimpleNode) tree;
    -            return node.isEvalChain((OgnlContext) context);
    +            OgnlContext ognlContext = null;
    +
    +            if (context!=null && context instanceof OgnlContext) {
    +                ognlContext = (OgnlContext) context;
    +            }
    +            return node.isEvalChain(ognlContext);
             }
             return false;
         }
     
         public Object getValue(String name, Map<String, Object> context, Object root) throws OgnlException {
    -        return Ognl.getValue(compile(name), context, root);
    +        return Ognl.getValue(compile(name, context), context, root);
         }
     
         public Object getValue(String name, Map<String, Object> context, Object root, Class resultType) throws OgnlException {
    -        return Ognl.getValue(compile(name), context, root, resultType);
    +        return Ognl.getValue(compile(name, context), context, root, resultType);
         }
     
     
         public Object compile(String expression) throws OgnlException {
    +        return compile(expression, null);
    +    }
    +
    +    public Object compile(String expression, Map<String, Object> context) throws OgnlException {
    +        Object tree;
             if (enableExpressionCache) {
    -            Object o = expressions.get(expression);
    -            if (o == null) {
    -                o = Ognl.parseExpression(expression);
    -                expressions.putIfAbsent(expression, o);
    +            tree = expressions.get(expression);
    +            if (tree == null) {
    +                tree = Ognl.parseExpression(expression);
    +                expressions.putIfAbsent(expression, tree);
                 }
    -            return o;
    -        } else
    -            return Ognl.parseExpression(expression);
    +        } else {
    +            tree = Ognl.parseExpression(expression);
    +        }
    +
    +        if (!enableEvalExpression && isEvalExpression(tree, context)) {
    +            throw new OgnlException("Eval expressions has been disabled");
    +        }
    +
    +        return tree;
         }
     
         /**
    @@ -312,7 +338,7 @@ public void copy(Object from, Object to, Map<String, Object> context, Collection
                         PropertyDescriptor toPd = toPdHash.get(fromPd.getName());
                         if ((toPd != null) && (toPd.getWriteMethod() != null)) {
                             try {
    -                            Object expr = compile(fromPd.getName());
    +                            Object expr = compile(fromPd.getName(), context);
                                 Object value = Ognl.getValue(expr, contextFrom, from);
                                 Ognl.setValue(expr, contextTo, to, value);
                             } catch (OgnlException e) {
    
  • xwork-core/src/main/java/com/opensymphony/xwork2/XWorkConstants.java+1 0 modified
    @@ -13,6 +13,7 @@ public final class XWorkConstants {
         public static final String DEV_MODE = "devMode";
         public static final String LOG_MISSING_PROPERTIES = "logMissingProperties";
         public static final String ENABLE_OGNL_EXPRESSION_CACHE = "enableOGNLExpressionCache";
    +    public static final String ENABLE_OGNL_EVAL_EXPRESSION = "enableOGNLEvalExpression";
         public static final String RELOAD_XML_CONFIGURATION = "reloadXmlConfiguration";
         public static final String ALLOW_STATIC_METHOD_ACCESS = "allowStaticMethodAccess";
         public static final String XWORK_LOGGER_FACTORY = "xwork.loggerFactory";
    

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

7

News mentions

0

No linked articles in our index yet.