[cxf] branch master updated: CXF-8025 - Specify a max stack depth to prevent recursion attacks

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[cxf] branch master updated: CXF-8025 - Specify a max stack depth to prevent recursion attacks

coheigea
Administrator
This is an automated email from the ASF dual-hosted git repository.

coheigea pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cxf.git


The following commit(s) were added to refs/heads/master by this push:
     new af2c8ec  CXF-8025 - Specify a max stack depth to prevent recursion attacks
af2c8ec is described below

commit af2c8ec3ea20d84504a8a7026a3b99ec1b1b081b
Author: Colm O hEigeartaigh <[hidden email]>
AuthorDate: Tue Oct 8 17:10:53 2019 +0100

    CXF-8025 - Specify a max stack depth to prevent recursion attacks
---
 .../org/apache/cxf/tools/common/ToolConstants.java    |  3 ++-
 .../tools/wsdlto/frontend/jaxws/jaxws-toolspec.xml    |  9 +++++++++
 .../jaxws/processor/internal/ProcessorUtil.java       | 18 ++++++++++++++----
 .../apache/cxf/tools/wsdlto/jaxws/CodeGenTest.java    | 19 +++++++++++++++++++
 4 files changed, 44 insertions(+), 5 deletions(-)

diff --git a/tools/common/src/main/java/org/apache/cxf/tools/common/ToolConstants.java b/tools/common/src/main/java/org/apache/cxf/tools/common/ToolConstants.java
index 9e15c43..3ffcd98 100644
--- a/tools/common/src/main/java/org/apache/cxf/tools/common/ToolConstants.java
+++ b/tools/common/src/main/java/org/apache/cxf/tools/common/ToolConstants.java
@@ -102,9 +102,10 @@ public final class ToolConstants {
     public static final String CFG_SEI_SUPER = "seiSuper";
     public static final String CFG_MARK_GENERATED = "markGenerated";
     public static final String CFG_SUPPRESS_GENERATED_DATE = "suppressGeneratedDate";
-    
+
     public static final String CFG_MARK_GENERATED_OPTION = "mark-generated";
     public static final String CFG_SUPPRESS_GENERATED_DATE_OPTION = "suppress-generated-date";
+    public static final String CFG_MAX_EXTENSION_STACK_DEPTH = "maxExtensionStackDepth";
 
     //Internal Flag to generate
     public static final String CFG_IMPL_CLASS = "implClass";
diff --git a/tools/wsdlto/frontend/jaxws/src/main/java/org/apache/cxf/tools/wsdlto/frontend/jaxws/jaxws-toolspec.xml b/tools/wsdlto/frontend/jaxws/src/main/java/org/apache/cxf/tools/wsdlto/frontend/jaxws/jaxws-toolspec.xml
index d5cda21..b5d524b 100644
--- a/tools/wsdlto/frontend/jaxws/src/main/java/org/apache/cxf/tools/wsdlto/frontend/jaxws/jaxws-toolspec.xml
+++ b/tools/wsdlto/frontend/jaxws/src/main/java/org/apache/cxf/tools/wsdlto/frontend/jaxws/jaxws-toolspec.xml
@@ -375,6 +375,15 @@ Examples:
                 </annotation>
                 <switch>suppress-generated-date</switch>
             </option>
+            <option id="maxExtensionStackDepth" maxOccurs="1">
+                <annotation>
+                    The maximum stack depth allowed when parsing schema extensions. The default is 5.
+                </annotation>
+                <switch>maxExtensionStackDepth</switch>
+                <associatedArgument placement="afterSpace">
+                    <annotation>maxExtensionStackDepth</annotation>
+                </associatedArgument>
+            </option>
         </optionGroup>
         <optionGroup id="common_options">
             <option id="help" maxOccurs="1">
diff --git a/tools/wsdlto/frontend/jaxws/src/main/java/org/apache/cxf/tools/wsdlto/frontend/jaxws/processor/internal/ProcessorUtil.java b/tools/wsdlto/frontend/jaxws/src/main/java/org/apache/cxf/tools/wsdlto/frontend/jaxws/processor/internal/ProcessorUtil.java
index 3c5a174..ea3fd34 100644
--- a/tools/wsdlto/frontend/jaxws/src/main/java/org/apache/cxf/tools/wsdlto/frontend/jaxws/processor/internal/ProcessorUtil.java
+++ b/tools/wsdlto/frontend/jaxws/src/main/java/org/apache/cxf/tools/wsdlto/frontend/jaxws/processor/internal/ProcessorUtil.java
@@ -41,6 +41,7 @@ import org.apache.cxf.common.xmlschema.SchemaCollection;
 import org.apache.cxf.helpers.JavaUtils;
 import org.apache.cxf.service.model.MessagePartInfo;
 import org.apache.cxf.service.model.ServiceInfo;
+import org.apache.cxf.tools.common.ToolConstants;
 import org.apache.cxf.tools.common.ToolContext;
 import org.apache.cxf.tools.common.model.DefaultValueWriter;
 import org.apache.cxf.tools.util.ClassCollector;
@@ -370,18 +371,27 @@ public final class ProcessorUtil {
 
         //If it's extension
         if (seq == null && type.getContentModel() != null) {
-            qnames.addAll(createWrappedElementsFromExtension(schema, type));
+            Object configuredMaxStackDepth = context.get(ToolConstants.CFG_MAX_EXTENSION_STACK_DEPTH);
+            Integer maxStackDepth = Integer.valueOf(5);
+            if (configuredMaxStackDepth instanceof Integer) {
+                maxStackDepth = (Integer)configuredMaxStackDepth;
+            } else if (configuredMaxStackDepth instanceof String) {
+                maxStackDepth = Integer.valueOf((String)configuredMaxStackDepth);
+            }
+            qnames.addAll(createWrappedElementsFromExtension(schema, type, maxStackDepth));
+
         }
 
         return qnames;
     }
 
     private static List<WrapperElement> createWrappedElementsFromExtension(SchemaCollection schema,
-                                                                           XmlSchemaComplexType type) {
+                                                                           XmlSchemaComplexType type,
+                                                                           int maxStackDepth) {
         List<WrapperElement> qnames = new ArrayList<>();
 
         XmlSchemaContent schemaContent = type.getContentModel().getContent();
-        if (!(schemaContent instanceof XmlSchemaComplexContentExtension)) {
+        if (!(schemaContent instanceof XmlSchemaComplexContentExtension) || maxStackDepth == 0) {
             return qnames;
         }
 
@@ -394,7 +404,7 @@ public final class ProcessorUtil {
 
             if (complexBaseType.getParticle() == null && complexBaseType.getContentModel() != null) {
                 // continue up the extension ladder
-                qnames.addAll(createWrappedElementsFromExtension(schema, complexBaseType));
+                qnames.addAll(createWrappedElementsFromExtension(schema, complexBaseType, maxStackDepth - 1));
             } else if (complexBaseType.getParticle() instanceof XmlSchemaSequence) {
                 XmlSchemaSequence seq = (XmlSchemaSequence)complexBaseType.getParticle();
                 qnames.addAll(createWrappedElements(seq));
diff --git a/tools/wsdlto/test/src/test/java/org/apache/cxf/tools/wsdlto/jaxws/CodeGenTest.java b/tools/wsdlto/test/src/test/java/org/apache/cxf/tools/wsdlto/jaxws/CodeGenTest.java
index 89e2c1e..6434448 100644
--- a/tools/wsdlto/test/src/test/java/org/apache/cxf/tools/wsdlto/jaxws/CodeGenTest.java
+++ b/tools/wsdlto/test/src/test/java/org/apache/cxf/tools/wsdlto/jaxws/CodeGenTest.java
@@ -1667,6 +1667,25 @@ public class CodeGenTest extends AbstractCodeGenTest {
     }
 
     @Test
+    public void testMultilevelExtensionWrapperStackDepth() throws Exception {
+        env.put(ToolConstants.CFG_WSDLURL,
+                getLocation("/wsdl2java_wsdl/cxf8025/hello_world_multilevel_extension_wrapped.wsdl"));
+        env.put(ToolConstants.CFG_MAX_EXTENSION_STACK_DEPTH, Integer.valueOf(3));
+        processor.setContext(env);
+        processor.execute();
+
+        File infFile = new File(output, "org/apache/cxf/w2j/multilevel_extension_wrapped/Greeter.java");
+        assertTrue(infFile.exists());
+
+        Class<?> interfaceClass = classLoader.loadClass("org.apache.cxf.w2j.multilevel_extension_wrapped.Greeter");
+
+        Method method = interfaceClass.getMethod("greetMeMultilevelExtension", new Class[] {
+            String.class, String.class, String.class
+        });
+        assertNotNull("greetMeMultilevelExtension operation is NOT generated correctly as excepted", method);
+    }
+
+    @Test
     public void testJavaDoc() throws Exception {
         env.put(ToolConstants.CFG_WSDLURL, getLocation("/wsdl2java_wsdl/hello_world.wsdl"));
         processor.setContext(env);