Skip to content

Commit 5d999d6

Browse files
committed
Adds a constant to control when proxy can be accessed
2 parents 8f53b6f + 0d6442b commit 5d999d6

File tree

7 files changed

+73
-1
lines changed

7 files changed

+73
-1
lines changed

core/src/main/java/com/opensymphony/xwork2/ognl/OgnlUtil.java

+12
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.apache.commons.lang3.BooleanUtils;
2929
import org.apache.logging.log4j.LogManager;
3030
import org.apache.logging.log4j.Logger;
31+
import org.apache.struts2.StrutsConstants;
3132

3233
import java.beans.BeanInfo;
3334
import java.beans.IntrospectionException;
@@ -64,6 +65,7 @@ public class OgnlUtil {
6465

6566
private Container container;
6667
private boolean allowStaticMethodAccess;
68+
private boolean disallowProxyMemberAccess;
6769

6870
@Inject
6971
public void setXWorkConverter(XWorkConverter conv) {
@@ -144,6 +146,15 @@ public void setAllowStaticMethodAccess(String allowStaticMethodAccess) {
144146
this.allowStaticMethodAccess = Boolean.parseBoolean(allowStaticMethodAccess);
145147
}
146148

149+
@Inject(value = StrutsConstants.STRUTS_DISALLOW_PROXY_MEMBER_ACCESS, required = false)
150+
public void setDisallowProxyMemberAccess(String disallowProxyMemberAccess) {
151+
this.disallowProxyMemberAccess = Boolean.parseBoolean(disallowProxyMemberAccess);
152+
}
153+
154+
public boolean isDisallowProxyMemberAccess() {
155+
return disallowProxyMemberAccess;
156+
}
157+
147158
/**
148159
* Sets the object's properties using the default type converter, defaulting to not throw
149160
* exceptions for problems setting the properties.
@@ -679,6 +690,7 @@ protected Map createDefaultContext(Object root, ClassResolver classResolver) {
679690
memberAccess.setExcludedClasses(excludedClasses);
680691
memberAccess.setExcludedPackageNamePatterns(excludedPackageNamePatterns);
681692
memberAccess.setExcludedPackageNames(excludedPackageNames);
693+
memberAccess.setDisallowProxyMemberAccess(disallowProxyMemberAccess);
682694

683695
return Ognl.createDefaultContext(root, resolver, defaultConverter, memberAccess);
684696
}

core/src/main/java/com/opensymphony/xwork2/ognl/OgnlValueStack.java

+1
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ public void setOgnlUtil(OgnlUtil ognlUtil) {
8484
securityMemberAccess.setExcludedClasses(ognlUtil.getExcludedClasses());
8585
securityMemberAccess.setExcludedPackageNamePatterns(ognlUtil.getExcludedPackageNamePatterns());
8686
securityMemberAccess.setExcludedPackageNames(ognlUtil.getExcludedPackageNames());
87+
securityMemberAccess.setDisallowProxyMemberAccess(ognlUtil.isDisallowProxyMemberAccess());
8788
}
8889

8990
protected void setRoot(XWorkConverter xworkConverter, CompoundRootAccessor accessor, CompoundRoot compoundRoot,

core/src/main/java/com/opensymphony/xwork2/ognl/SecurityMemberAccess.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public class SecurityMemberAccess extends DefaultMemberAccess {
4141
private Set<Class<?>> excludedClasses = Collections.emptySet();
4242
private Set<Pattern> excludedPackageNamePatterns = Collections.emptySet();
4343
private Set<String> excludedPackageNames = Collections.emptySet();
44+
private boolean disallowProxyMemberAccess;
4445

4546
public SecurityMemberAccess(boolean method) {
4647
super(false);
@@ -85,7 +86,7 @@ public boolean isAccessible(Map context, Object target, Member member, String pr
8586
return false;
8687
}
8788

88-
if (ProxyUtil.isProxyMember(member, target)) {
89+
if (disallowProxyMemberAccess && ProxyUtil.isProxyMember(member, target)) {
8990
LOG.warn("Access to proxy [{}] is blocked!", member);
9091
return false;
9192
}
@@ -212,4 +213,8 @@ public void setExcludedPackageNamePatterns(Set<Pattern> excludedPackageNamePatte
212213
public void setExcludedPackageNames(Set<String> excludedPackageNames) {
213214
this.excludedPackageNames = excludedPackageNames;
214215
}
216+
217+
public void setDisallowProxyMemberAccess(boolean disallowProxyMemberAccess) {
218+
this.disallowProxyMemberAccess = disallowProxyMemberAccess;
219+
}
215220
}

core/src/main/java/org/apache/struts2/StrutsConstants.java

+2
Original file line numberDiff line numberDiff line change
@@ -325,4 +325,6 @@ public final class StrutsConstants {
325325
public static final String STRUTS_TEXT_PROVIDER_FACTORY = "struts.textProviderFactory";
326326

327327
public static final String STRUTS_LOCALIZED_TEXT_PROVIDER = "struts.localizedTextProvider";
328+
329+
public static final String STRUTS_DISALLOW_PROXY_MEMBER_ACCESS = "struts.disallowProxyMemberAccess";
328330
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package com.opensymphony.xwork2.ognl;
2+
3+
import java.lang.reflect.Member;
4+
import java.util.HashMap;
5+
import java.util.Map;
6+
7+
import com.opensymphony.xwork2.ActionProxy;
8+
import com.opensymphony.xwork2.XWorkTestCase;
9+
import com.opensymphony.xwork2.config.providers.XmlConfigurationProvider;
10+
11+
public class SecurityMemberAccessProxyTest extends XWorkTestCase {
12+
private Map<String, Object> context;
13+
14+
@Override
15+
public void setUp() throws Exception {
16+
super.setUp();
17+
18+
context = new HashMap<>();
19+
// Set up XWork
20+
XmlConfigurationProvider provider = new XmlConfigurationProvider("com/opensymphony/xwork2/spring/actionContext-xwork.xml");
21+
container.inject(provider);
22+
loadConfigurationProviders(provider);
23+
}
24+
25+
public void testProxyAccessIsBlocked() throws Exception {
26+
ActionProxy proxy = actionProxyFactory.createActionProxy(null,
27+
"chaintoAOPedTestSubBeanAction", null, context);
28+
29+
SecurityMemberAccess sma = new SecurityMemberAccess(false);
30+
sma.setDisallowProxyMemberAccess(true);
31+
32+
Member member = proxy.getAction().getClass().getMethod("isExposeProxy");
33+
34+
boolean accessible = sma.isAccessible(context, proxy.getAction(), member, "");
35+
assertFalse(accessible);
36+
}
37+
38+
public void testProxyAccessIsAccessible() throws Exception {
39+
ActionProxy proxy = actionProxyFactory.createActionProxy(null,
40+
"chaintoAOPedTestSubBeanAction", null, context);
41+
42+
SecurityMemberAccess sma = new SecurityMemberAccess(false);
43+
44+
Member member = proxy.getAction().getClass().getMethod("isExposeProxy");
45+
46+
boolean accessible = sma.isAccessible(context, proxy.getAction(), member, "");
47+
assertTrue(accessible);
48+
}
49+
}

core/src/test/resources/com/opensymphony/xwork2/spring/actionContext-xwork.xml

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
<xwork>
33
<bean type="com.opensymphony.xwork2.ObjectFactory" class="com.opensymphony.xwork2.spring.SpringObjectFactory" />
44
<constant name="applicationContextPath" value="com/opensymphony/xwork2/spring/actionContext-spring.xml" />
5+
<constant name="struts.disallowProxyMemberAccess" value="true" />
56
<package name="default">
67
<result-types>
78
<result-type name="null" class="com.opensymphony.xwork2.mock.MockResult" default="true"/>

plugins/spring/src/main/resources/struts-plugin.xml

+2
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
<constant name="struts.class.reloading.acceptClasses" value="" />
3636
<constant name="struts.class.reloading.reloadConfig" value="false" />
3737

38+
<constant name="struts.disallowProxyMemberAccess" value="true" />
39+
3840
<package name="spring-default">
3941
<interceptors>
4042
<interceptor name="autowiring" class="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor"/>

0 commit comments

Comments
 (0)