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(+)
----------------------------------------------------------------------