Search code examples
javaspringweb-servicescxf

Setting Apache CXF bus properties for malicious xml


I am trying to set CXF bus properties for malicious xml as below

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sec="http://cxf.apache.org/configuration/security"
    xmlns:http="http://cxf.apache.org/transports/http/configuration"
    xmlns:cxf="http://cxf.apache.org/core"
    xsi:schemaLocation="
      http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd
      http://cxf.apache.org/configuration/security http://cxf.apache.org/schemas/configuration/security.xsd
      http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd
      http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

    <cxf:bus>
        <cxf:properties>
            <entry key="org.apache.cxf.stax.maxAttributeSize" value="1"/>
            <entry key="org.apache.cxf.stax.maxChildElements" value="1"/>
            <entry key="org.apache.cxf.stax.maxElementDepth" value="1"/>
            <entry key="org.apache.cxf.stax.maxAttributeCount" value="1"/> 
            <entry key="org.apache.cxf.stax.maxTextLength" value="1"/>
            <entry key="org.apache.cxf.stax.maxElementCount" value="1"/>
      </cxf:properties>
    </cxf:bus>
</beans>

It seems like these properties are not picked up by CXF. Above code is in spring context xml file. Whenever I do a post request which has more than one elements and child elements, CXF does not throw any error. I am using CXF version 3.1.1


Solution

  • I have tested the Bus properties with CXF 2.7.13 and 3.1.6 in a Tomcat server with java 1.6 and java 1.8, and in both cases the XML request was blocked as the documentation says.

    Make sure woodstook and stax libraries are in classpath. CXF delegates XML check to those libraries. If the server has it owns XML parser. They have to be before the XML parser server (if available). Check server configuration guide

    I am going to detail the configuration so you can check yours.

    CXF Dependencies (Ivy format)

     <dependency org="org.apache.cxf" name="cxf-rt-frontend-jaxrs" rev="3.1.6" conf="default"/>
     <dependency org="org.apache.cxf" name="cxf-rt-frontend-jaxws" rev="3.1.6" conf="default"/>
     <dependency org="org.apache.cxf" name="cxf-rt-ws-security" rev="3.1.6" conf="default"/>
     <dependency org="org.apache.cxf" name="cxf-rt-rs-extension-providers" rev="3.1.6" conf="default"/>
    

    spring CXF config

    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
        xmlns:jaxrs="http://cxf.apache.org/jaxrs" xmlns:jaxws="http://cxf.apache.org/jaxws"
        xmlns:http-conf="http://cxf.apache.org/transports/http/configuration"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:cxf="http://cxf.apache.org/core"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
            http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd
            http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
            http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd 
            http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd"
        default-lazy-init="false">
    
        <import resource="classpath:META-INF/cxf/cxf.xml" />
    
        <!-- JAX-WS server-->
        <bean id="sampleEndPointImpl" class="com.SampleEndPointImpl" />
        <jaxws:endpoint id="sampleServiceSOAP" 
            address="/sampleEndPoint"
            endpointName = "SampleEndPoint"
            implementor="#sampleEndPointImpl" >
        </jaxws:endpoint>
    
        <!-- JAX-RS server-->
        <bean id="bookService" class="com.BookService" />
        <jaxrs:server id="bookservice" address="/">
            <jaxrs:serviceBeans>
                <ref bean="bookService" />
            </jaxrs:serviceBeans>
        </jaxrs:server>
    
        <cxf:bus>
            <cxf:properties>
                <entry key="org.apache.cxf.stax.maxAttributeSize" value="1"/>
                <entry key="org.apache.cxf.stax.maxChildElements" value="1"/>
                <entry key="org.apache.cxf.stax.maxElementDepth" value="1"/>
                <entry key="org.apache.cxf.stax.maxAttributeCount" value="1"/> 
                <entry key="org.apache.cxf.stax.maxTextLength" value="1"/>
                <entry key="org.apache.cxf.stax.maxElementCount" value="1"/>
          </cxf:properties>
    
        </cxf:bus>
    
    
    </beans>
    

    Sample REST server

    BookService.java

     @POST
     @Path("/test")
     @Consumes(MediaType.APPLICATION_XML)
     public Response test(Book book) {
        return Response.ok(book.getName() + "123").build();
     }
    

    Book.java

     @XmlRootElement(name = "Book")
     public class Book {
         private String name;
    
         public String getName() {return name;}
         public void setName(String name) {this.name = name;}
     }
    

    Request tested

     POST /test
     Content-Type:application/xml
     <Book><name>aaaa</name></Book>
    

    The error received

     JAXBException occurred : Maximum Element Depth limit (1) Exceeded. Maximum Element Depth limit (1) Exceeded. 
    

    If you delete the <cxf:bus> section, CXF default values will be applied, and the XML example will be processed

     aaaa123