Skip to content

Commit

Permalink
Disable eval expressions
Browse files Browse the repository at this point in the history
  • Loading branch information
mcucchiara committed Apr 18, 2013
1 parent 9fbb0d9 commit 7e6f641
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 13 deletions.
3 changes: 3 additions & 0 deletions core/src/main/java/org/apache/struts2/StrutsConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}

Expand Down
52 changes: 39 additions & 13 deletions xwork-core/src/main/java/com/opensymphony/xwork2/ognl/OgnlUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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.
Expand Down Expand Up @@ -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");
}
Expand All @@ -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;
}

/**
Expand Down Expand Up @@ -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) {
Expand Down

0 comments on commit 7e6f641

Please sign in to comment.