From af961bd888b05caea907256b431ea2a8e4fa4bf3 Mon Sep 17 00:00:00 2001 From: Maurizio Cucchiara Date: Mon, 10 Jun 2013 16:15:42 +0000 Subject: [PATCH] WW-4073 - Disable eval expressions and simple JSTL accessibility git-svn-id: https://svn.apache.org/repos/asf/struts/struts2/trunk@1491521 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/struts2/StrutsConstants.java | 3 + .../apache/struts2/dispatcher/Dispatcher.java | 18 ++++- .../dispatcher/StrutsRequestWrapper.java | 68 +++++++++++-------- 3 files changed, 60 insertions(+), 29 deletions(-) diff --git a/core/src/main/java/org/apache/struts2/StrutsConstants.java b/core/src/main/java/org/apache/struts2/StrutsConstants.java index eb8fe6fcd..00fe463aa 100644 --- a/core/src/main/java/org/apache/struts2/StrutsConstants.java +++ b/core/src/main/java/org/apache/struts2/StrutsConstants.java @@ -231,6 +231,9 @@ public final class StrutsConstants { /** Enables evaluation of OGNL expressions **/ public static final String STRUTS_ENABLE_OGNL_EVAL_EXPRESSION = "struts.ognl.enableOGNLEvalExpression"; + /** Disables {@link org.apache.struts2.dispatcher.StrutsRequestWrapper} request attribute value stack lookup (JSTL accessibility) **/ + public static final String STRUTS_DISABLE_REQUEST_ATTRIBUTE_VALUE_STACK_LOOKUP = "struts.disableRequestAttributeValueStackLookup"; + /** The{@link org.apache.struts2.views.util.UrlHelper} implementation class **/ public static final String STRUTS_URL_HELPER = "struts.view.urlHelper"; diff --git a/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java b/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java index 4b6a5ebc5..9f4d01cb5 100644 --- a/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java +++ b/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java @@ -119,10 +119,15 @@ public class Dispatcher { private ConfigurationManager configurationManager; /** - * Store state of StrutsConstants.STRUTS_DEVMODE setting. + * Store state of StrutsConstants.STRUTS_DEVMODE setting. */ private boolean devMode; + /** + * Store state of StrutsConstants.DISABLE_REQUEST_ATTRIBUTE_VALUE_STACK_LOOKUP setting. + */ + private boolean disableRequestAttributeValueStackLookup; + /** * Store state of StrutsConstants.STRUTS_I18N_ENCODING setting. */ @@ -225,6 +230,15 @@ public class Dispatcher { devMode = "true".equals(mode); } + /** + * Modify state of StrutsConstants.DISABLE_REQUEST_ATTRIBUTE_VALUE_STACK_LOOKUP setting. + * @param disableRequestAttributeValueStackLookup New setting + */ + @Inject(value=StrutsConstants.STRUTS_DISABLE_REQUEST_ATTRIBUTE_VALUE_STACK_LOOKUP, required=false) + public void setDisableRequestAttributeValueStackLookup(String disableRequestAttributeValueStackLookup) { + this.disableRequestAttributeValueStackLookup = "true".equalsIgnoreCase(disableRequestAttributeValueStackLookup); + } + /** * Modify state of StrutsConstants.STRUTS_LOCALE setting. * @param val New setting @@ -781,7 +795,7 @@ public class Dispatcher { LocaleProvider provider = getContainer().getInstance(LocaleProvider.class); request = new MultiPartRequestWrapper(mpr, request, getSaveDir(servletContext), provider); } else { - request = new StrutsRequestWrapper(request); + request = new StrutsRequestWrapper(request, disableRequestAttributeValueStackLookup); } return request; diff --git a/core/src/main/java/org/apache/struts2/dispatcher/StrutsRequestWrapper.java b/core/src/main/java/org/apache/struts2/dispatcher/StrutsRequestWrapper.java index effdc56e1..9daa3f173 100644 --- a/core/src/main/java/org/apache/struts2/dispatcher/StrutsRequestWrapper.java +++ b/core/src/main/java/org/apache/struts2/dispatcher/StrutsRequestWrapper.java @@ -21,11 +21,13 @@ package org.apache.struts2.dispatcher; +import com.opensymphony.xwork2.ActionContext; +import com.opensymphony.xwork2.util.ValueStack; + import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; -import com.opensymphony.xwork2.ActionContext; -import com.opensymphony.xwork2.util.ValueStack; +import static org.apache.commons.lang3.BooleanUtils.isTrue; /** * @@ -41,49 +43,61 @@ import com.opensymphony.xwork2.util.ValueStack; */ public class StrutsRequestWrapper extends HttpServletRequestWrapper { + private static final String REQUEST_WRAPPER_GET_ATTRIBUTE = "__requestWrapper.getAttribute"; + private final boolean disableRequestAttributeValueStackLookup; + /** * The constructor * @param req The request */ public StrutsRequestWrapper(HttpServletRequest req) { + this(req, false); + } + + /** + * The constructor + * @param req The request + * @param disableRequestAttributeValueStackLookup flag for disabling request attribute value stack lookup (JSTL accessibility) + */ + public StrutsRequestWrapper(HttpServletRequest req, boolean disableRequestAttributeValueStackLookup) { super(req); + this.disableRequestAttributeValueStackLookup = disableRequestAttributeValueStackLookup; } /** * Gets the object, looking in the value stack if not found * - * @param s The attribute key + * @param key The attribute key */ - public Object getAttribute(String s) { - if (s != null && s.startsWith("javax.servlet")) { + public Object getAttribute(String key) { + if (key == null) { + throw new NullPointerException("You must specify a key value"); + } + + if (disableRequestAttributeValueStackLookup || key.startsWith("javax.servlet")) { // don't bother with the standard javax.servlet attributes, we can short-circuit this // see WW-953 and the forums post linked in that issue for more info - return super.getAttribute(s); + return super.getAttribute(key); } ActionContext ctx = ActionContext.getContext(); - Object attribute = super.getAttribute(s); - if (ctx != null) { - if (attribute == null) { - boolean alreadyIn = false; - Boolean b = (Boolean) ctx.get("__requestWrapper.getAttribute"); - if (b != null) { - alreadyIn = b.booleanValue(); - } - - // note: we don't let # come through or else a request for - // #attr.foo or #request.foo could cause an endless loop - if (!alreadyIn && s.indexOf("#") == -1) { - try { - // If not found, then try the ValueStack - ctx.put("__requestWrapper.getAttribute", Boolean.TRUE); - ValueStack stack = ctx.getValueStack(); - if (stack != null) { - attribute = stack.findValue(s); - } - } finally { - ctx.put("__requestWrapper.getAttribute", Boolean.FALSE); + Object attribute = super.getAttribute(key); + + if (ctx != null && attribute == null) { + boolean alreadyIn = isTrue((Boolean) ctx.get(REQUEST_WRAPPER_GET_ATTRIBUTE)); + + // note: we don't let # come through or else a request for + // #attr.foo or #request.foo could cause an endless loop + if (!alreadyIn && !key.contains("#")) { + try { + // If not found, then try the ValueStack + ctx.put(REQUEST_WRAPPER_GET_ATTRIBUTE, Boolean.TRUE); + ValueStack stack = ctx.getValueStack(); + if (stack != null) { + attribute = stack.findValue(key); } + } finally { + ctx.put(REQUEST_WRAPPER_GET_ATTRIBUTE, Boolean.FALSE); } } }