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&amp;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("&", "&amp;");
+                                xml = xml.replaceAll(">", "&gt;");
+                                xml = xml.replaceAll("<", "&lt;");
                             }
-                        });
-                } 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("&", "&amp;");
-                                    xml = xml.replaceAll(">", "&gt;");
-                                    xml = xml.replaceAll("<", "&lt;");
-                                }
-                                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;
     }
 }