[ 
https://issues.apache.org/jira/browse/WW-5364?focusedWorklogId=893745&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-893745
 ]

ASF GitHub Bot logged work on WW-5364:
--------------------------------------

                Author: ASF GitHub Bot
            Created on: 04/Dec/23 11:44
            Start Date: 04/Dec/23 11:44
    Worklog Time Spent: 10m 
      Work Description: kusalk commented on code in PR #800:
URL: https://github.com/apache/struts/pull/800#discussion_r1413740321


##########
core/src/main/java/com/opensymphony/xwork2/XWorkJUnit4TestCase.java:
##########


Review Comment:
   Moved this here so that we can utilise it for tests in core



##########
apps/showcase/src/main/resources/struts.xml:
##########
@@ -34,6 +34,19 @@
     <constant name="struts.custom.i18n.resources" value="globalMessages" />
     <constant name="struts.action.extension" value="action,," />
 
+    <constant name="struts.allowlist.enable" value="true" />

Review Comment:
   It works!



##########
core/src/main/java/com/opensymphony/xwork2/ognl/SecurityMemberAccess.java:
##########
@@ -65,12 +80,14 @@ public class SecurityMemberAccess implements MemberAccess {
     private Set<String> excludedPackageNames = emptySet();
     private Set<String> excludedPackageExemptClasses = emptySet();
     private boolean enforceAllowlistEnabled = false;
-    private Set<String> allowlistClasses = emptySet();
+    private Set<Class<?>> allowlistClasses = emptySet();

Review Comment:
   While we use `String` comparison for the exclusion list, we use `Class` 
comparison for the allowlist to prevent accidentally allowing through another 
Class with the same name (in applications with multiple classloaders)



##########
core/src/main/resources/struts-beans.xml:
##########
@@ -169,6 +169,7 @@
     <bean name="struts" 
class="com.opensymphony.xwork2.ognl.SecurityMemberAccess" scope="prototype"/>
     <bean type="org.apache.struts2.ognl.OgnlGuard" name="struts"
           class="org.apache.struts2.ognl.StrutsOgnlGuard"/>
+    <bean class="org.apache.struts2.ognl.ProviderAllowlist"/>

Review Comment:
   No extension point - can't see any use for one



##########
plugins/junit/src/main/java/org/apache/struts2/junit/XWorkJUnit4TestCase.java:
##########
@@ -18,74 +18,5 @@
  */
 package org.apache.struts2.junit;
 
-import com.opensymphony.xwork2.ActionProxyFactory;
-import com.opensymphony.xwork2.config.Configuration;
-import com.opensymphony.xwork2.config.ConfigurationException;
-import com.opensymphony.xwork2.config.ConfigurationManager;
-import com.opensymphony.xwork2.config.ConfigurationProvider;
-import com.opensymphony.xwork2.inject.Container;
-import com.opensymphony.xwork2.inject.ContainerBuilder;
-import com.opensymphony.xwork2.inject.Context;
-import com.opensymphony.xwork2.inject.Factory;
-import com.opensymphony.xwork2.inject.Scope;
-import com.opensymphony.xwork2.test.StubConfigurationProvider;
-import com.opensymphony.xwork2.util.XWorkTestCaseHelper;
-import com.opensymphony.xwork2.util.location.LocatableProperties;
-import org.junit.After;
-import org.junit.Before;
-
-public abstract class XWorkJUnit4TestCase {
-
-    protected ConfigurationManager configurationManager;
-    protected Configuration configuration;
-    protected Container container;
-    protected ActionProxyFactory actionProxyFactory;
-
-    @Before
-    public void setUp() throws Exception {
-        configurationManager = XWorkTestCaseHelper.setUp();
-        configuration = configurationManager.getConfiguration();
-        container = configuration.getContainer();
-        actionProxyFactory = container.getInstance(ActionProxyFactory.class);
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        XWorkTestCaseHelper.tearDown(configurationManager);
-        configurationManager = null;
-        configuration = null;
-        container = null;
-        actionProxyFactory = null;
-    }
-
-    protected void loadConfigurationProviders(ConfigurationProvider... 
providers) {
-        configurationManager = 
XWorkTestCaseHelper.loadConfigurationProviders(configurationManager, providers);
-        configuration = configurationManager.getConfiguration();
-        container = configuration.getContainer();
-        actionProxyFactory = container.getInstance(ActionProxyFactory.class);
-    }
-
-    protected void loadButAdd(final Class<?> type, final Object impl) {
-        loadButAdd(type, Container.DEFAULT_NAME, impl);
-    }
-
-    protected void loadButAdd(final Class<?> type, final String name, final 
Object impl) {
-        loadConfigurationProviders(new StubConfigurationProvider() {
-            @Override
-            public void register(ContainerBuilder builder,
-                                 LocatableProperties props) throws 
ConfigurationException {
-                builder.factory(type, name, new Factory() {
-                    public Object create(Context context) throws Exception {
-                        return impl;
-                    }
-
-                    @Override
-                    public Class type() {
-                        return impl.getClass();
-                    }
-                }, Scope.SINGLETON);
-            }
-        });
-    }
-
+public abstract class XWorkJUnit4TestCase extends 
com.opensymphony.xwork2.XWorkJUnit4TestCase {

Review Comment:
   Extended the moved class for compat



##########
core/src/main/resources/struts-default.xml:
##########
@@ -44,8 +44,6 @@
 
         <interceptors>
             <interceptor name="alias" 
class="com.opensymphony.xwork2.interceptor.AliasInterceptor"/>
-            <interceptor name="autowiring"

Review Comment:
   This class isn't provided by core



##########
plugins/junit/src/main/java/org/apache/struts2/junit/XWorkTestCase.java:
##########
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.struts2.junit;
+
+public abstract class XWorkTestCase extends 
com.opensymphony.xwork2.XWorkTestCase {

Review Comment:
   Added this for consistency



##########
core/src/main/java/com/opensymphony/xwork2/config/providers/XmlDocConfigurationProvider.java:
##########


Review Comment:
   Made some changes to this file to attempt to load every class defined in a 
`package` and add it to the allowlist



##########
core/src/main/java/com/opensymphony/xwork2/config/impl/DefaultConfiguration.java:
##########
@@ -395,6 +359,57 @@ protected Container 
createBootstrapContainer(List<ContainerProvider> providers)
         return builder.create(true);
     }
 
+    public static ContainerBuilder bootstrapFactories(ContainerBuilder 
builder) {

Review Comment:
   Extracted code into this method for reuse by the 
`StrutsDefaultConfigurationProvider`



##########
core/src/main/java/com/opensymphony/xwork2/ognl/SecurityMemberAccess.java:
##########
@@ -57,6 +59,19 @@ public class SecurityMemberAccess implements MemberAccess {
 
     private static final Logger LOG = 
LogManager.getLogger(SecurityMemberAccess.class);
 
+    private static final Set<String> ALLOWLIST_REQUIRED_PACKAGES = 
unmodifiableSet(new HashSet<>(Arrays.asList(

Review Comment:
   Required system allowlist defined here - it's possible I've missed some 
packages/classes, can add as needed



##########
core/src/test/java/com/opensymphony/xwork2/config/providers/ConfigurationProviderOgnlAllowlistTest.java:
##########
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.config.providers;
+
+import com.opensymphony.xwork2.XWorkJUnit4TestCase;
+import com.opensymphony.xwork2.config.ConfigurationProvider;
+import org.apache.struts2.config.StrutsXmlConfigurationProvider;
+import org.apache.struts2.ognl.ProviderAllowlist;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class ConfigurationProviderOgnlAllowlistTest extends 
XWorkJUnit4TestCase {
+
+    private final ConfigurationProvider testXml1 = new 
StrutsXmlConfigurationProvider("com/opensymphony/xwork2/config/providers/xwork-test-allowlist.xml");
+    private final ConfigurationProvider testXml2 = new 
StrutsXmlConfigurationProvider("com/opensymphony/xwork2/config/providers/xwork-test-allowlist-2.xml");
+    private ProviderAllowlist providerAllowlist;
+
+    @Before
+    public void setUp() throws Exception {
+        loadConfigurationProviders(testXml1, testXml2);
+        providerAllowlist = container.getInstance(ProviderAllowlist.class);
+    }
+
+    @Test
+    public void allowlist() throws Exception {
+        loadConfigurationProviders(testXml1, testXml2);
+        providerAllowlist = container.getInstance(ProviderAllowlist.class);
+
+        
assertThat(providerAllowlist.getProviderAllowlist()).containsExactlyInAnyOrder(
+                
Class.forName("com.opensymphony.xwork2.interceptor.ValidationAware"),
+                Class.forName("com.opensymphony.xwork2.LocaleProvider"),
+                Class.forName("java.io.Serializable"),
+                Class.forName("com.opensymphony.xwork2.mock.MockResult"),
+                
Class.forName("com.opensymphony.xwork2.interceptor.ConditionalInterceptor"),
+                Class.forName("com.opensymphony.xwork2.ActionSupport"),
+                Class.forName("com.opensymphony.xwork2.ActionChainResult"),
+                Class.forName("com.opensymphony.xwork2.TextProvider"),
+                
Class.forName("org.apache.struts2.interceptor.NoOpInterceptor"),
+                
Class.forName("com.opensymphony.xwork2.interceptor.Interceptor"),
+                Class.forName("java.lang.Object"),

Review Comment:
   Even though `java.lang.Object` is added to the allowlist as it is a 
superclass, the exclusion list always takes precedence and so this class will 
not be allowed in practice





Issue Time Tracking
-------------------

    Worklog Id:     (was: 893745)
    Time Spent: 1h 40m  (was: 1.5h)

> Automatically populate OGNL allowlist
> -------------------------------------
>
>                 Key: WW-5364
>                 URL: https://issues.apache.org/jira/browse/WW-5364
>             Project: Struts 2
>          Issue Type: Improvement
>          Components: Core
>            Reporter: Kusal Kithul-Godage
>            Priority: Minor
>             Fix For: 6.4.0
>
>          Time Spent: 1h 40m
>  Remaining Estimate: 0h
>




--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to