This is an automated email from the ASF dual-hosted git repository. lukaszlenart pushed a commit to branch WW-5604-cdi-proxy-detection in repository https://gitbox.apache.org/repos/asf/struts.git
commit 196b105d0f48d80b3c6d40cfcf8d147a6e2fd7e9 Author: Lukasz Lenart <[email protected]> AuthorDate: Mon Jul 20 14:28:30 2026 +0200 WW-5604 Address review: positive allowlist test, guard Weld member check, fix javadoc Co-Authored-By: Claude Opus 4.8 <[email protected]> --- .../org/apache/struts2/cdi/CdiProxyService.java | 11 ++++++++--- .../CdiSecurityMemberAccessProxyTest.java | 22 +++++++++++++++++++--- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/plugins/cdi/src/main/java/org/apache/struts2/cdi/CdiProxyService.java b/plugins/cdi/src/main/java/org/apache/struts2/cdi/CdiProxyService.java index 637287bb8..67dba2cc8 100644 --- a/plugins/cdi/src/main/java/org/apache/struts2/cdi/CdiProxyService.java +++ b/plugins/cdi/src/main/java/org/apache/struts2/cdi/CdiProxyService.java @@ -27,13 +27,15 @@ import org.jboss.weld.proxy.WeldClientProxy; import java.lang.reflect.Member; import java.lang.reflect.Method; +import static java.lang.reflect.Modifier.isStatic; + /** * CDI-aware {@link org.apache.struts2.util.ProxyService}. Extends the default * {@link StrutsProxyService} (Spring + Hibernate detection) with recognition of * Weld client proxies, so {@code SecurityMemberAccess} can resolve the real * target class of a normal-scoped CDI bean before evaluating the OGNL allowlist. * - * @see WW-5604 + * @see <a href="https://issues.apache.org/jira/browse/WW-5604">WW-5604</a> */ public class CdiProxyService extends StrutsProxyService { @@ -49,7 +51,7 @@ public class CdiProxyService extends StrutsProxyService { @Override public boolean isProxyMember(Member member, Object object) { - return super.isProxyMember(member, object) || isWeldProxyMember(member); + return super.isProxyMember(member, object) || isWeldProxyMember(member, object); } @Override @@ -80,7 +82,10 @@ public class CdiProxyService extends StrutsProxyService { } } - private boolean isWeldProxyMember(Member member) { + private boolean isWeldProxyMember(Member member, Object object) { + if (!isStatic(member.getModifiers()) && !isWeldProxy(object)) { + return false; + } try { if (member instanceof Method method) { return MethodUtils.getMatchingMethod(WeldClientProxy.class, member.getName(), method.getParameterTypes()) != null; diff --git a/plugins/cdi/src/test/java/org/apache/struts2/cdi/CdiSecurityMemberAccessProxyTest.java b/plugins/cdi/src/test/java/org/apache/struts2/ognl/CdiSecurityMemberAccessProxyTest.java similarity index 79% rename from plugins/cdi/src/test/java/org/apache/struts2/cdi/CdiSecurityMemberAccessProxyTest.java rename to plugins/cdi/src/test/java/org/apache/struts2/ognl/CdiSecurityMemberAccessProxyTest.java index 6d6a74914..fe1e6daf6 100644 --- a/plugins/cdi/src/test/java/org/apache/struts2/cdi/CdiSecurityMemberAccessProxyTest.java +++ b/plugins/cdi/src/test/java/org/apache/struts2/ognl/CdiSecurityMemberAccessProxyTest.java @@ -16,12 +16,12 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.struts2.cdi; +package org.apache.struts2.ognl; import ognl.Ognl; import ognl.OgnlContext; -import org.apache.struts2.ognl.SecurityMemberAccess; -import org.apache.struts2.ognl.StrutsProxyCacheFactory; +import org.apache.struts2.cdi.CdiProxyService; +import org.apache.struts2.cdi.ProxiedFooService; import org.apache.struts2.util.ProxyService; import org.jboss.weld.bootstrap.api.helpers.RegistrySingletonProvider; import org.jboss.weld.environment.se.Weld; @@ -33,6 +33,7 @@ import org.junit.BeforeClass; import org.junit.Test; import java.lang.reflect.Member; +import java.lang.reflect.Method; import static org.assertj.core.api.Assertions.assertThat; @@ -85,4 +86,19 @@ public class CdiSecurityMemberAccessProxyTest { // The Weld proxy accessor is a proxy member -> blocked. assertThat(sma.isAccessible(context, proxy, proxyMember, "")).isFalse(); } + + /** + * When the allowlist is enabled and proxy object access is allowed, a Weld client proxy must be allowlisted based + * on its underlying target class ({@code ProxiedFooService}), not the proxy class. This is the core WW-5604 scenario. + */ + @Test + public void classInclusion_weldProxy_allowProxyObjectAccess() throws Exception { + Method realMethod = proxy.getClass().getMethod("getHello"); + + sma.useEnforceAllowlistEnabled(Boolean.TRUE.toString()); + sma.useDisallowProxyObjectAccess(Boolean.FALSE.toString()); + sma.useAllowlistClasses(ProxiedFooService.class.getName()); + + assertThat(sma.checkAllowlist(proxy, realMethod)).isTrue(); + } }
