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 2017/06/29 07:42:02 UTC

[1/2] struts git commit: WW-4805 Blocks ognl access to class members of Spring proxy

Repository: struts
Updated Branches:
  refs/heads/support-2-3 73da12e72 -> ae5630197


WW-4805 Blocks ognl access to class members of Spring proxy


Project: http://git-wip-us.apache.org/repos/asf/struts/repo
Commit: http://git-wip-us.apache.org/repos/asf/struts/commit/583da3d5
Tree: http://git-wip-us.apache.org/repos/asf/struts/tree/583da3d5
Diff: http://git-wip-us.apache.org/repos/asf/struts/diff/583da3d5

Branch: refs/heads/support-2-3
Commit: 583da3d5df5aeeded3beadca6305a98c5618e46b
Parents: 9e8627c
Author: Yasser Zamani <ya...@live.com>
Authored: Wed Jun 21 16:40:29 2017 +0430
Committer: Yasser Zamani <ya...@live.com>
Committed: Wed Jun 21 16:40:29 2017 +0430

----------------------------------------------------------------------
 .../xwork2/ognl/SecurityMemberAccess.java       |   6 +
 .../com/opensymphony/xwork2/util/ProxyUtil.java | 151 +++++++++++++++++++
 .../xwork2/spring/ActionsFromSpringTest.java    |  26 ++++
 .../xwork2/spring/actionContext-xwork.xml       |  10 ++
 4 files changed, 193 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/struts/blob/583da3d5/xwork-core/src/main/java/com/opensymphony/xwork2/ognl/SecurityMemberAccess.java
----------------------------------------------------------------------
diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/ognl/SecurityMemberAccess.java b/xwork-core/src/main/java/com/opensymphony/xwork2/ognl/SecurityMemberAccess.java
index 53f8848..6ff74f1 100644
--- a/xwork-core/src/main/java/com/opensymphony/xwork2/ognl/SecurityMemberAccess.java
+++ b/xwork-core/src/main/java/com/opensymphony/xwork2/ognl/SecurityMemberAccess.java
@@ -15,6 +15,7 @@
  */
 package com.opensymphony.xwork2.ognl;
 
+import com.opensymphony.xwork2.util.ProxyUtil;
 import com.opensymphony.xwork2.util.logging.Logger;
 import com.opensymphony.xwork2.util.logging.LoggerFactory;
 import ognl.DefaultMemberAccess;
@@ -93,6 +94,11 @@ public class SecurityMemberAccess extends DefaultMemberAccess {
             return false;
         }
 
+        if (ProxyUtil.isProxyMember(member, target)) {
+            LOG.warn("Access to proxy [#0] is blocked!", member);
+            return false;
+        }
+
         boolean allow = true;
         if (!checkStaticMethodAccess(member)) {
             if (LOG.isTraceEnabled()) {

http://git-wip-us.apache.org/repos/asf/struts/blob/583da3d5/xwork-core/src/main/java/com/opensymphony/xwork2/util/ProxyUtil.java
----------------------------------------------------------------------
diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/util/ProxyUtil.java b/xwork-core/src/main/java/com/opensymphony/xwork2/util/ProxyUtil.java
new file mode 100644
index 0000000..57eb98b
--- /dev/null
+++ b/xwork-core/src/main/java/com/opensymphony/xwork2/util/ProxyUtil.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright 2017 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.opensymphony.xwork2.util;
+
+import org.apache.commons.lang3.reflect.ConstructorUtils;
+import org.apache.commons.lang3.reflect.FieldUtils;
+import org.apache.commons.lang3.reflect.MethodUtils;
+
+import java.lang.reflect.*;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * <code>ProxyUtil</code>
+ * <p>
+ * Various utility methods dealing with proxies
+ * </p>
+ *
+ */
+public class ProxyUtil {
+    private static final String SPRING_ADVISED_CLASS_NAME = "org.springframework.aop.framework.Advised";
+    private static final String SPRING_SPRINGPROXY_CLASS_NAME = "org.springframework.aop.SpringProxy";
+    private static final String SPRING_TARGETCLASSAWARE_CLASS_NAME = "org.springframework.aop.TargetClassAware";
+
+    private static final Map<Class<?>, Boolean> isProxyCache =
+            new ConcurrentHashMap<Class<?>, Boolean>(256);
+    private static final Map<Member, Boolean> isProxyMemberCache =
+            new ConcurrentHashMap<Member, Boolean>(256);
+
+    /**
+     * Check whether the given member is a proxy member of a proxy object.
+     * @param member the member to check
+     * @param object the object to check
+     */
+    public static boolean isProxyMember(Member member, Object object) {
+        if (!isProxy(object))
+            return false;
+
+        Boolean flag = isProxyMemberCache.get(member);
+        if (flag != null) {
+            return flag;
+        }
+
+        boolean isProxyMember = isSpringProxyMember(member);
+
+        isProxyMemberCache.put(member, isProxyMember);
+        return isProxyMember;
+    }
+
+    /**
+     * Check whether the given object is a proxy.
+     * @param object the object to check
+     */
+    private static boolean isProxy(Object object) {
+        Class<?> clazz = object.getClass();
+        Boolean flag = isProxyCache.get(clazz);
+        if (flag != null) {
+            return flag;
+        }
+
+        boolean isProxy = isSpringAopProxy(object);
+
+        isProxyCache.put(clazz, isProxy);
+        return isProxy;
+    }
+
+    /**
+     * Check whether the given object is a Spring proxy.
+     * @param object the object to check
+     */
+    private static boolean isSpringAopProxy(Object object) {
+        Class<?> clazz = object.getClass();
+        return (implementsInterface(clazz, SPRING_SPRINGPROXY_CLASS_NAME) && (Proxy.isProxyClass(clazz)
+                || isCglibProxyClass(clazz)));
+    }
+
+    /**
+     * Check whether the given member is a member of a spring proxy.
+     * @param member the member to check
+     */
+    private static boolean isSpringProxyMember(Member member) {
+        try {
+            Class<?> clazz = ClassLoaderUtil.loadClass(SPRING_ADVISED_CLASS_NAME, ProxyUtil.class);
+            if (hasMember(clazz, member))
+                return true;
+            clazz = ClassLoaderUtil.loadClass(SPRING_TARGETCLASSAWARE_CLASS_NAME, ProxyUtil.class);
+            if (hasMember(clazz, member))
+                return true;
+            clazz = ClassLoaderUtil.loadClass(SPRING_SPRINGPROXY_CLASS_NAME, ProxyUtil.class);
+            if (hasMember(clazz, member))
+                return true;
+        } catch (ClassNotFoundException ignored) {
+        }
+
+        return false;
+    }
+
+    /**
+     * Check whether the specified class is a CGLIB-generated class.
+     * @param clazz the class to check
+     */
+    private static boolean isCglibProxyClass(Class<?> clazz) {
+        return (clazz != null && clazz.getName().contains("$$"));
+    }
+
+    /**
+     * Check whether the given class implements an interface with a given class name.
+     * @param clazz the class to check
+     * @param ifaceClassName the interface class name to check
+     */
+    private static boolean implementsInterface(Class<?> clazz, String ifaceClassName) {
+        try {
+            Class<?> ifaceClass = ClassLoaderUtil.loadClass(ifaceClassName, ProxyUtil.class);
+            return ifaceClass.isAssignableFrom(clazz);
+        } catch (ClassNotFoundException e) {
+            return false;
+        }
+    }
+
+    /**
+     * Check whether the given class has a given member.
+     * @param clazz the class to check
+     * @param member the member to check
+     */
+    private static boolean hasMember(Class<?> clazz, Member member) {
+        if (member instanceof Method) {
+            return null != MethodUtils.getMatchingAccessibleMethod(clazz, member.getName(), ((Method) member).getParameterTypes());
+        }
+        if (member instanceof Field) {
+            return null != FieldUtils.getField(clazz, member.getName(), true);
+        }
+        if (member instanceof Constructor) {
+            return null != ConstructorUtils.getMatchingAccessibleConstructor(clazz, ((Constructor) member).getParameterTypes());
+        }
+
+        return false;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/struts/blob/583da3d5/xwork-core/src/test/java/com/opensymphony/xwork2/spring/ActionsFromSpringTest.java
----------------------------------------------------------------------
diff --git a/xwork-core/src/test/java/com/opensymphony/xwork2/spring/ActionsFromSpringTest.java b/xwork-core/src/test/java/com/opensymphony/xwork2/spring/ActionsFromSpringTest.java
index f6cbecd..114a875 100644
--- a/xwork-core/src/test/java/com/opensymphony/xwork2/spring/ActionsFromSpringTest.java
+++ b/xwork-core/src/test/java/com/opensymphony/xwork2/spring/ActionsFromSpringTest.java
@@ -5,8 +5,12 @@ package com.opensymphony.xwork2.spring;
 
 import com.opensymphony.xwork2.*;
 import com.opensymphony.xwork2.config.providers.XmlConfigurationProvider;
+import org.apache.commons.lang3.reflect.MethodUtils;
 import org.springframework.context.ApplicationContext;
 
+import java.util.HashMap;
+import java.util.Map;
+
 /**
  * Test loading actions from the Spring Application Context.
  *
@@ -77,4 +81,26 @@ public class ActionsFromSpringTest extends XWorkTestCase {
     	        assertTrue(springResult.isInitialize());
     	        assertNotNull(springResult.getStringParameter());
     }
+
+    public void testProxiedActionIsNotAccessible() throws Exception {
+        // given
+        Map<String, Object> params = new HashMap<String, Object>();
+        params.put("exposeProxy", "true");
+        params.put("blah", "S2-047");
+
+        HashMap<String, Object> extraContext = new HashMap<String, Object>();
+        extraContext.put(ActionContext.PARAMETERS, params);
+
+        ActionProxy proxy = actionProxyFactory.createActionProxy(null,
+                "paramsAwareProxiedAction", null, extraContext);
+
+        // when
+        proxy.execute();
+        Object action = proxy.getAction();
+
+        //then
+        assertEquals("S2-047", ((SimpleAction) action).getBlah());
+        assertFalse("proxied action is accessible!",
+                (Boolean) MethodUtils.invokeMethod(action, "isExposeProxy"));
+    }
 }

http://git-wip-us.apache.org/repos/asf/struts/blob/583da3d5/xwork-core/src/test/resources/com/opensymphony/xwork2/spring/actionContext-xwork.xml
----------------------------------------------------------------------
diff --git a/xwork-core/src/test/resources/com/opensymphony/xwork2/spring/actionContext-xwork.xml b/xwork-core/src/test/resources/com/opensymphony/xwork2/spring/actionContext-xwork.xml
index 988956f..928d37f 100644
--- a/xwork-core/src/test/resources/com/opensymphony/xwork2/spring/actionContext-xwork.xml
+++ b/xwork-core/src/test/resources/com/opensymphony/xwork2/spring/actionContext-xwork.xml
@@ -8,6 +8,11 @@
             <result-type name="springResult" class="springResult" />
         </result-types>
 
+        <interceptors>
+            <interceptor name="params"
+                         class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>
+        </interceptors>
+
 		<action name="simpleAction" class="simple-action"/>
 
         <action name="dependencyAction" class="dependency-action"/>
@@ -19,5 +24,10 @@
         <action name="simpleActionSpringResult" class="simple-action">
 			<result name="error" type="springResult"/>
 		</action>
+
+        <action name="paramsAwareProxiedAction" class="proxied-action">
+            <interceptor-ref name="params" />
+            <result name="input" type="null"/>
+        </action>
     </package>
 </xwork>


[2/2] struts git commit: WW-4805 Ports proxy detection to 2.3

Posted by lu...@apache.org.
WW-4805 Ports proxy detection to 2.3


Project: http://git-wip-us.apache.org/repos/asf/struts/repo
Commit: http://git-wip-us.apache.org/repos/asf/struts/commit/ae563019
Tree: http://git-wip-us.apache.org/repos/asf/struts/tree/ae563019
Diff: http://git-wip-us.apache.org/repos/asf/struts/diff/ae563019

Branch: refs/heads/support-2-3
Commit: ae5630197980fe431f84eb26523f3b23b71f91bc
Parents: 73da12e 583da3d
Author: Lukasz Lenart <lu...@apache.org>
Authored: Thu Jun 29 09:41:53 2017 +0200
Committer: Lukasz Lenart <lu...@apache.org>
Committed: Thu Jun 29 09:41:53 2017 +0200

----------------------------------------------------------------------
 .../xwork2/ognl/SecurityMemberAccess.java       |   6 +
 .../com/opensymphony/xwork2/util/ProxyUtil.java | 151 +++++++++++++++++++
 .../xwork2/spring/ActionsFromSpringTest.java    |  26 ++++
 .../xwork2/spring/actionContext-xwork.xml       |  10 ++
 4 files changed, 193 insertions(+)
----------------------------------------------------------------------