You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by lu...@apache.org on 2020/01/31 18:46:05 UTC
[struts] branch WW-5054-debug-browser updated: WW-5054 Ignores
internal security in devMode
This is an automated email from the ASF dual-hosted git repository.
lukaszlenart pushed a commit to branch WW-5054-debug-browser
in repository https://gitbox.apache.org/repos/asf/struts.git
The following commit(s) were added to refs/heads/WW-5054-debug-browser by this push:
new 3afd682 WW-5054 Ignores internal security in devMode
3afd682 is described below
commit 3afd68214b289516501dd5ec0983b829b6c9c73b
Author: Lukasz Lenart <lu...@apache.org>
AuthorDate: Fri Jan 31 19:45:49 2020 +0100
WW-5054 Ignores internal security in devMode
---
.../com/opensymphony/xwork2/ognl/OgnlUtil.java | 51 ++---
.../debugging/DebuggingInterceptor.java | 211 ++++++++++-----------
2 files changed, 117 insertions(+), 145 deletions(-)
diff --git a/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlUtil.java b/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlUtil.java
index 9798974..88b54cc 100644
--- a/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlUtil.java
+++ b/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlUtil.java
@@ -54,7 +54,7 @@ public class OgnlUtil {
private static final Logger LOG = LogManager.getLogger(OgnlUtil.class);
private final ConcurrentMap<String, Object> expressions = new ConcurrentHashMap<>();
- private final ConcurrentMap<Class, BeanInfo> beanInfoCache = new ConcurrentHashMap<>();
+ private final ConcurrentMap<Class<?>, BeanInfo> beanInfoCache = new ConcurrentHashMap<>();
private TypeConverter defaultConverter;
private boolean devMode;
@@ -65,10 +65,6 @@ public class OgnlUtil {
private Set<Pattern> excludedPackageNamePatterns;
private Set<String> excludedPackageNames;
- private Set<Class<?>> excludedClassesCopy;
- private Set<Pattern> excludedPackageNamePatternsCopy;
- private Set<String> excludedPackageNamesCopy;
-
private Container container;
private boolean allowStaticFieldAccess = true;
private boolean allowStaticMethodAccess;
@@ -115,33 +111,6 @@ public class OgnlUtil {
this.excludedClasses = Collections.unmodifiableSet(excludedClasses);
}
- public void avoidAccessControl() {
- if (devMode) {
- LOG.warn("Cleans up excluded classes and packages in devMode");
- excludedClassesCopy = new HashSet<>(excludedClasses);
- excludedClasses = Collections.unmodifiableSet(new HashSet<>());
-
- excludedPackageNamePatternsCopy = new HashSet<>(excludedPackageNamePatterns);
- excludedPackageNamePatterns = Collections.unmodifiableSet(new HashSet<>());
-
- excludedPackageNamesCopy = new HashSet<>(excludedPackageNames);
- excludedPackageNames = Collections.unmodifiableSet(new HashSet<>());
- }
- }
- public void restoreAccessControl() {
- if (devMode) {
- LOG.warn("Restores excluded classes and packages in devMode");
- excludedClasses = Collections.unmodifiableSet(excludedClassesCopy);
- excludedClassesCopy = null;
-
- excludedPackageNamePatterns = Collections.unmodifiableSet(excludedPackageNamePatternsCopy);
- excludedPackageNamePatternsCopy = null;
-
- excludedPackageNames = Collections.unmodifiableSet(excludedPackageNamesCopy);
- excludedPackageNamesCopy = null;
- }
- }
-
private Set<Class<?>> parseExcludedClasses(String commaDelimitedClasses) {
Set<String> classNames = TextParseUtil.commaDelimitedStringToSet(commaDelimitedClasses);
Set<Class<?>> classes = new HashSet<>();
@@ -370,7 +339,7 @@ public class OgnlUtil {
* problems setting the properties
*/
public void setProperties(Map<String, ?> properties, Object o, boolean throwPropertyExceptions) {
- Map context = createDefaultContext(o);
+ Map<String, Object> context = createDefaultContext(o);
setProperties(properties, o, context, throwPropertyExceptions);
}
@@ -818,21 +787,25 @@ public class OgnlUtil {
}
}
- protected Map createDefaultContext(Object root) {
+ protected Map<String, Object> createDefaultContext(Object root) {
return createDefaultContext(root, null);
}
- protected Map createDefaultContext(Object root, ClassResolver classResolver) {
+ protected Map<String, Object> createDefaultContext(Object root, ClassResolver classResolver) {
ClassResolver resolver = classResolver;
if (resolver == null) {
resolver = container.getInstance(CompoundRootAccessor.class);
}
SecurityMemberAccess memberAccess = new SecurityMemberAccess(allowStaticMethodAccess, allowStaticFieldAccess);
- memberAccess.setExcludedClasses(excludedClasses);
- memberAccess.setExcludedPackageNamePatterns(excludedPackageNamePatterns);
- memberAccess.setExcludedPackageNames(excludedPackageNames);
- memberAccess.setDisallowProxyMemberAccess(disallowProxyMemberAccess);
+ if (devMode) {
+ LOG.warn("Working in devMode, ignoring internal security");
+ } else {
+ memberAccess.setExcludedClasses(excludedClasses);
+ memberAccess.setExcludedPackageNamePatterns(excludedPackageNamePatterns);
+ memberAccess.setExcludedPackageNames(excludedPackageNames);
+ memberAccess.setDisallowProxyMemberAccess(disallowProxyMemberAccess);
+ }
return Ognl.createDefaultContext(root, memberAccess, resolver, defaultConverter);
}
diff --git a/core/src/main/java/org/apache/struts2/interceptor/debugging/DebuggingInterceptor.java b/core/src/main/java/org/apache/struts2/interceptor/debugging/DebuggingInterceptor.java
index ff7e2d3..6791f81 100644
--- a/core/src/main/java/org/apache/struts2/interceptor/debugging/DebuggingInterceptor.java
+++ b/core/src/main/java/org/apache/struts2/interceptor/debugging/DebuggingInterceptor.java
@@ -23,7 +23,6 @@ import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.inject.Inject;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import com.opensymphony.xwork2.interceptor.PreResultListener;
-import com.opensymphony.xwork2.ognl.OgnlUtil;
import com.opensymphony.xwork2.util.ValueStack;
import com.opensymphony.xwork2.util.reflection.ReflectionProvider;
import org.apache.logging.log4j.LogManager;
@@ -44,7 +43,12 @@ import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
/**
* <!-- START SNIPPET: description -->
@@ -66,7 +70,7 @@ import java.util.*;
* the 'xml' mode is inserted at the top of the page.</li>
* <li> <code>command</code> - Tests an OGNL expression and returns the
* string result. Only used by the OGNL console.</li>
- * <li><code>browser</code> Shows field values of an object specified in the
+ * <li><code>browser</code> Shows field values of an object specified in the
* <code>object</code> parameter (#context by default). When the <code>object</code>
* parameters is set, the '#' character needs to be escaped to '%23'. Like
* debug=browser&object=%23parameters</li>
@@ -94,9 +98,9 @@ public class DebuggingInterceptor extends AbstractInterceptor {
private final static Logger LOG = LogManager.getLogger(DebuggingInterceptor.class);
private String[] ignorePrefixes = new String[]{"org.apache.struts.",
- "com.opensymphony.xwork2.", "xwork."};
+ "com.opensymphony.xwork2.", "xwork."};
private String[] _ignoreKeys = new String[]{"application", "session",
- "parameters", "request"};
+ "parameters", "request"};
private HashSet<String> ignoreKeys = new HashSet<>(Arrays.asList(_ignoreKeys));
private final static String XML_MODE = "xml";
@@ -112,10 +116,10 @@ public class DebuggingInterceptor extends AbstractInterceptor {
private final static String DECORATE_PARAM = "decorate";
private boolean enableXmlWithConsole = false;
-
+
private boolean devMode;
private FreemarkerManager freemarkerManager;
-
+
private boolean consoleEnabled = false;
private ReflectionProvider reflectionProvider;
@@ -123,12 +127,12 @@ public class DebuggingInterceptor extends AbstractInterceptor {
public void setDevMode(String mode) {
this.devMode = "true".equals(mode);
}
-
+
@Inject
public void setFreemarkerManager(FreemarkerManager mgr) {
this.freemarkerManager = mgr;
}
-
+
@Inject
public void setReflectionProvider(ReflectionProvider reflectionProvider) {
this.reflectionProvider = reflectionProvider;
@@ -146,105 +150,100 @@ public class DebuggingInterceptor extends AbstractInterceptor {
boolean devMode = devModeOverride != null ? devModeOverride : this.devMode;
if (devMode) {
final ActionContext ctx = ActionContext.getContext();
- ctx.getInstance(OgnlUtil.class).avoidAccessControl();;
- try {
- String type = getParameter(DEBUG_PARAM);
- ctx.getParameters().remove(DEBUG_PARAM);
- if (XML_MODE.equals(type)) {
- inv.addPreResultListener(
- new PreResultListener() {
- public void beforeResult(ActionInvocation inv, String result) {
- printContext();
+ String type = getParameter(DEBUG_PARAM);
+ ctx.getParameters().remove(DEBUG_PARAM);
+ if (XML_MODE.equals(type)) {
+ inv.addPreResultListener(
+ new PreResultListener() {
+ public void beforeResult(ActionInvocation inv, String result) {
+ printContext();
+ }
+ });
+ } else if (CONSOLE_MODE.equals(type)) {
+ consoleEnabled = true;
+ inv.addPreResultListener(
+ new PreResultListener() {
+ public void beforeResult(ActionInvocation inv, String actionResult) {
+ String xml = "";
+ if (enableXmlWithConsole) {
+ StringWriter writer = new StringWriter();
+ printContext(new PrettyPrintWriter(writer));
+ xml = writer.toString();
+ xml = xml.replaceAll("&", "&");
+ xml = xml.replaceAll(">", ">");
+ xml = xml.replaceAll("<", "<");
}
- });
- } else if (CONSOLE_MODE.equals(type)) {
- consoleEnabled = true;
- inv.addPreResultListener(
- new PreResultListener() {
- public void beforeResult(ActionInvocation inv, String actionResult) {
- String xml = "";
- if (enableXmlWithConsole) {
- StringWriter writer = new StringWriter();
- printContext(new PrettyPrintWriter(writer));
- xml = writer.toString();
- xml = xml.replaceAll("&", "&");
- xml = xml.replaceAll(">", ">");
- xml = xml.replaceAll("<", "<");
- }
- ActionContext.getContext().put("debugXML", xml);
+ ActionContext.getContext().put("debugXML", xml);
+
+ FreemarkerResult result = new FreemarkerResult();
+ result.setFreemarkerManager(freemarkerManager);
+ result.setContentType("text/html");
+ result.setLocation("/org/apache/struts2/interceptor/debugging/console.ftl");
+ result.setParse(false);
+ try {
+ result.execute(inv);
+ } catch (Exception ex) {
+ LOG.error("Unable to create debugging console", ex);
+ }
+
+ }
+ });
+ } else if (COMMAND_MODE.equals(type)) {
+ ValueStack stack = (ValueStack) ctx.getSession().get(SESSION_KEY);
+ if (stack == null) {
+ //allows it to be embedded on another page
+ stack = (ValueStack) ctx.get(ActionContext.VALUE_STACK);
+ ctx.getSession().put(SESSION_KEY, stack);
+ }
+ String cmd = getParameter(EXPRESSION_PARAM);
+
+ ServletActionContext.getRequest().setAttribute("decorator", "none");
+ HttpServletResponse res = ServletActionContext.getResponse();
+ res.setContentType("text/plain");
+
+ try (PrintWriter writer =
+ ServletActionContext.getResponse().getWriter()) {
+ writer.print(stack.findValue(cmd));
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ }
+ cont = false;
+ } else if (BROWSER_MODE.equals(type)) {
+ actionOnly = true;
+ inv.addPreResultListener(
+ new PreResultListener() {
+ public void beforeResult(ActionInvocation inv, String actionResult) {
+ String rootObjectExpression = getParameter(OBJECT_PARAM);
+ if (rootObjectExpression == null)
+ rootObjectExpression = "top";
+ String decorate = getParameter(DECORATE_PARAM);
+ ValueStack stack = (ValueStack) ctx.get(ActionContext.VALUE_STACK);
+ Object rootObject = stack.findValue(rootObjectExpression);
+
+ try (StringWriter writer = new StringWriter()) {
+ ObjectToHTMLWriter htmlWriter = new ObjectToHTMLWriter(writer);
+ htmlWriter.write(reflectionProvider, rootObject, rootObjectExpression);
+ String html = writer.toString();
+ writer.close();
+
+ stack.set("debugHtml", html);
+
+ //on the first request, response can be decorated
+ //but we need plain text on the other ones
+ if ("false".equals(decorate))
+ ServletActionContext.getRequest().setAttribute("decorator", "none");
FreemarkerResult result = new FreemarkerResult();
result.setFreemarkerManager(freemarkerManager);
result.setContentType("text/html");
- result.setLocation("/org/apache/struts2/interceptor/debugging/console.ftl");
- result.setParse(false);
- try {
- result.execute(inv);
- } catch (Exception ex) {
- LOG.error("Unable to create debugging console", ex);
- }
-
+ result.setLocation("/org/apache/struts2/interceptor/debugging/browser.ftl");
+ result.execute(inv);
+ } catch (Exception ex) {
+ LOG.error("Unable to create debugging console", ex);
}
- });
- } else if (COMMAND_MODE.equals(type)) {
- ValueStack stack = (ValueStack) ctx.getSession().get(SESSION_KEY);
- if (stack == null) {
- //allows it to be embedded on another page
- stack = (ValueStack) ctx.get(ActionContext.VALUE_STACK);
- ctx.getSession().put(SESSION_KEY, stack);
- }
- String cmd = getParameter(EXPRESSION_PARAM);
-
- ServletActionContext.getRequest().setAttribute("decorator", "none");
- HttpServletResponse res = ServletActionContext.getResponse();
- res.setContentType("text/plain");
-
- try (PrintWriter writer =
- ServletActionContext.getResponse().getWriter()) {
- writer.print(stack.findValue(cmd));
- } catch (IOException ex) {
- ex.printStackTrace();
- }
- cont = false;
- } else if (BROWSER_MODE.equals(type)) {
- actionOnly = true;
- inv.addPreResultListener(
- new PreResultListener() {
- public void beforeResult(ActionInvocation inv, String actionResult) {
- String rootObjectExpression = getParameter(OBJECT_PARAM);
- if (rootObjectExpression == null)
- rootObjectExpression = "top";
- String decorate = getParameter(DECORATE_PARAM);
- ValueStack stack = (ValueStack) ctx.get(ActionContext.VALUE_STACK);
- Object rootObject = stack.findValue(rootObjectExpression);
-
- try (StringWriter writer = new StringWriter()) {
- ObjectToHTMLWriter htmlWriter = new ObjectToHTMLWriter(writer);
- htmlWriter.write(reflectionProvider, rootObject, rootObjectExpression);
- String html = writer.toString();
- writer.close();
-
- stack.set("debugHtml", html);
-
- //on the first request, response can be decorated
- //but we need plain text on the other ones
- if ("false".equals(decorate))
- ServletActionContext.getRequest().setAttribute("decorator", "none");
-
- FreemarkerResult result = new FreemarkerResult();
- result.setFreemarkerManager(freemarkerManager);
- result.setContentType("text/html");
- result.setLocation("/org/apache/struts2/interceptor/debugging/browser.ftl");
- result.execute(inv);
- } catch (Exception ex) {
- LOG.error("Unable to create debugging console", ex);
- }
- }
- });
- }
- } finally {
- ctx.getInstance(OgnlUtil.class).restoreAccessControl();
+ }
+ });
}
}
if (cont) {
@@ -286,7 +285,7 @@ public class DebuggingInterceptor extends AbstractInterceptor {
try {
PrettyPrintWriter writer = new PrettyPrintWriter(
- ServletActionContext.getResponse().getWriter());
+ ServletActionContext.getResponse().getWriter());
printContext(writer);
writer.close();
} catch (IOException ex) {
@@ -427,10 +426,10 @@ public class DebuggingInterceptor extends AbstractInterceptor {
private List<Object> filterValueStack(Map requestMap) {
List<Object> filter = new ArrayList<>();
Object valueStack = requestMap.get("struts.valueStack");
- if(valueStack != null) {
- filter.add(valueStack);
- }
- return filter;
+ if (valueStack != null) {
+ filter.add(valueStack);
+ }
+ return filter;
}
}