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

Reply via email to