VYPR
High severityNVD Advisory· Published Sep 24, 2012· Updated Apr 29, 2026

CVE-2012-3451

CVE-2012-3451

Description

Apache CXF before 2.4.9, 2.5.x before 2.5.5, and 2.6.x before 2.6.2 allows remote attackers to execute unintended web-service operations by sending a header with a SOAP Action String that is inconsistent with the message body.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
org.apache.cxf:cxfMaven
< 2.4.92.4.9
org.apache.cxf:cxfMaven
>= 2.5.0, < 2.5.52.5.5
org.apache.cxf:cxfMaven
>= 2.6.0, < 2.6.22.6.2

Affected products

2

Patches

4
deeeaa95a861

Merged revisions 1368608 via git cherry-pick from

https://github.com/apache/cxfColm O HeigeartaighAug 2, 2012via ghsa
10 files changed · +760 21
  • rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/Messages.properties+1 0 modified
    @@ -31,3 +31,4 @@ INVALID_11_VERSION=A SOAP 1.2 message is not valid when sent to a SOAP 1.1 only
     NO_NAMESPACE=No namespace on "{0}" element.
     BP_2211_RPCLIT_CANNOT_BE_NULL=Cannot write part {0}. RPC/Literal parts cannot be null. (WS-I BP R2211)
     UNKNOWN_RPC_LIT_PART=Found element {0} but could not find matching RPC/Literal part
    +SOAP_ACTION_MISMATCH=The given SOAPAction {0} does not match an operation.
    
  • rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/SoapActionInInterceptor.java+52 14 modified
    @@ -22,12 +22,14 @@
     import java.util.Collection;
     import java.util.List;
     import java.util.Map;
    +import java.util.logging.Logger;
     
     import org.apache.cxf.binding.soap.Soap11;
     import org.apache.cxf.binding.soap.Soap12;
     import org.apache.cxf.binding.soap.SoapBindingConstants;
     import org.apache.cxf.binding.soap.SoapMessage;
     import org.apache.cxf.binding.soap.model.SoapOperationInfo;
    +import org.apache.cxf.common.logging.LogUtils;
     import org.apache.cxf.common.util.StringUtils;
     import org.apache.cxf.endpoint.Endpoint;
     import org.apache.cxf.helpers.CastUtils;
    @@ -40,6 +42,8 @@
     
     public class SoapActionInInterceptor extends AbstractSoapInterceptor {
         
    +    private static final Logger LOG = LogUtils.getL7dLogger(SoapActionInInterceptor.class);
    +    
         public SoapActionInInterceptor() {
             super(Phase.READ);
             addAfter(ReadHeadersInterceptor.class.getName());
    @@ -91,6 +95,10 @@ public static String getSoapAction(Message m) {
         }
         
         public void handleMessage(SoapMessage message) throws Fault {
    +        if (isRequestor(message)) {
    +            return;
    +        }
    +        
             String action = getSoapAction(message);
             if (!StringUtils.isEmpty(action)) {
                 getAndSetOperation(message, action);
    @@ -108,24 +116,54 @@ private void getAndSetOperation(SoapMessage message, String action) {
             
             BindingOperationInfo bindingOp = null;
             
    -        Collection<BindingOperationInfo> bops = ep.getBinding().getBindingInfo().getOperations();
    -        if (bops == null) {
    -            return;
    -        }
    -        for (BindingOperationInfo boi : bops) {
    -            SoapOperationInfo soi = (SoapOperationInfo) boi.getExtensor(SoapOperationInfo.class);
    -            if (soi != null && action.equals(soi.getAction())) {
    -                if (bindingOp != null) {
    -                    //more than one op with the same action, will need to parse normally
    -                    return;
    +        Collection<BindingOperationInfo> bops = ep.getEndpointInfo()
    +            .getBinding().getOperations();
    +        if (bops != null) {
    +            for (BindingOperationInfo boi : bops) {
    +                SoapOperationInfo soi = boi.getExtensor(SoapOperationInfo.class);
    +                if (soi != null && action.equals(soi.getAction())) {
    +                    if (bindingOp != null) {
    +                        //more than one op with the same action, will need to parse normally
    +                        return;
    +                    }
    +                    bindingOp = boi;
                     }
    -                bindingOp = boi;
                 }
             }
    -        if (bindingOp != null) {
    -            ex.put(BindingOperationInfo.class, bindingOp);
    -            ex.put(OperationInfo.class, bindingOp.getOperationInfo());
    +        
    +        if (bindingOp == null) {
    +            //we didn't match the an operation, we'll try again later to make
    +            //sure the incoming message did end up matching an operation.
    +            //This could occur in some cases like WS-RM and WS-SecConv that will
    +            //intercept the message with a new endpoint/operation
    +            message.getInterceptorChain().add(new SoapActionInAttemptTwoInterceptor());
    +            return;
    +        }
    +
    +        ex.put(BindingOperationInfo.class, bindingOp);
    +        ex.put(OperationInfo.class, bindingOp.getOperationInfo());
    +    }
    +    
    +    public static class SoapActionInAttemptTwoInterceptor extends AbstractSoapInterceptor {
    +        public SoapActionInAttemptTwoInterceptor() {
    +            super(Phase.PRE_LOGICAL);
    +        }
    +        public void handleMessage(SoapMessage message) throws Fault {
    +            BindingOperationInfo boi = message.getExchange().getBindingOperationInfo();
    +            if (boi == null) {
    +                return;
    +            }
    +            String action = getSoapAction(message);
    +            if (StringUtils.isEmpty(action)) {
    +                return;
    +            }
    +            SoapOperationInfo soi = boi.getExtensor(SoapOperationInfo.class);
    +            if (soi == null || action.equals(soi.getAction())) {
    +                return;
    +            }
    +            throw new Fault("SOAP_ACTION_MISMATCH", LOG, null, action);
             }
         }
     
    +
     }
    
  • rt/core/src/main/java/org/apache/cxf/interceptor/DocLiteralInInterceptor.java+43 6 modified
    @@ -192,12 +192,11 @@ public void handleMessage(Message message) {
                         } else {
                             p = findMessagePart(exchange, operations, elName, client, paramNum, message);
                         }
    -    
    -                    if (p == null) {
    -                        throw new Fault(new org.apache.cxf.common.i18n.Message("NO_PART_FOUND", LOG, elName),
    -                                        Fault.FAULT_CODE_CLIENT);
    -                    }
    -    
    +                    
    +                    //Make sure the elName found on the wire is actually OK for 
    +                    //the purpose we need it
    +                    validatePart(p, elName, si);
    +
                         o = dr.read(p, xmlReader);
                         if (Boolean.TRUE.equals(si.getProperty("soap.force.doclit.bare")) 
                             && parameters.isEmpty()) {
    @@ -224,6 +223,44 @@ public void handleMessage(Message message) {
             }
         }
         
    +    private void validatePart(MessagePartInfo p, QName elName, ServiceInfo si) {
    +        if (p == null) {
    +            throw new Fault(new org.apache.cxf.common.i18n.Message("NO_PART_FOUND", LOG, elName),
    +                            Fault.FAULT_CODE_CLIENT);
    +
    +        }
    +
    +        Boolean synth = Boolean.FALSE;
    +        if (p.getMessageInfo() != null && p.getMessageInfo().getOperation() != null) {
    +            OperationInfo op = p.getMessageInfo().getOperation();
    +            Boolean b = (Boolean)op.getProperty("operation.is.synthetic");
    +            if (b != null) {
    +                synth = b;
    +            }
    +        }
    +        if (si != null && Boolean.TRUE.equals(si.getProperty("soap.force.doclit.bare"))) {
    +            // something like a Provider service or similar that is forcing a
    +            // doc/lit/bare on an endpoint that may not really be doc/lit/bare.  
    +            // we need to just let these through per spec so the endpoint
    +            // can process it
    +            synth = true;
    +        }
    +        if (p.isElement()) {
    +            if (p.getConcreteName() != null
    +                && !elName.equals(p.getConcreteName())
    +                && !Boolean.TRUE.equals(synth)) {
    +                throw new Fault("UNEXPECTED_ELEMENT", LOG, null, elName,
    +                                p.getConcreteName());
    +            }
    +        } else {
    +            if (!(elName.equals(p.getName()) || elName.equals(p.getConcreteName()))
    +                && !Boolean.TRUE.equals(synth)) {
    +                throw new Fault("UNEXPECTED_ELEMENT", LOG, null, elName,
    +                                p.getConcreteName());
    +            }
    +        }
    +    }
    +    
         private void getPara(DepthXMLStreamReader xmlReader,
                              DataReader<XMLStreamReader> dr,
                              MessageContentsList parameters,
    
  • rt/core/src/main/java/org/apache/cxf/interceptor/Messages.properties+1 0 modified
    @@ -40,4 +40,5 @@ COULD_NOT_FIND_SEICLASS=Could not find the class: {0}
     EXCEPTION_WHILE_WRITING_FAULT = Exception occurred while writing fault.
     EXCEPTION_WHILE_CREATING_EXCEPTION = Exception occurred while creating exception: {0}
     UNEXPECTED_WRAPPER_ELEMENT = Unexpected wrapper element {0} found.   Expected {1}.
    +UNEXPECTED_ELEMENT = Unexpected element {0} found.   Expected {1}.
      
    
  • systests/uncategorized/src/test/java/org/apache/cxf/systest/soap/RPCEncodedSoapActionGreeterImpl.java+40 0 added
    @@ -0,0 +1,40 @@
    +/**
    + * 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.cxf.systest.soap;
    +
    +import javax.jws.WebService;
    +import javax.jws.soap.SOAPBinding;
    +
    +import org.apache.hello_world_soap_action.WrappedGreeter;
    +
    +@WebService(endpointInterface = "org.apache.hello_world_soap_action.WrappedGreeter", 
    +serviceName = "WrappedSOAPService")
    +@SOAPBinding(style = SOAPBinding.Style.RPC, use = SOAPBinding.Use.ENCODED)
    +public class RPCEncodedSoapActionGreeterImpl implements WrappedGreeter {
    +
    +    public String sayHiRequestWrapped(String in) {
    +        return "sayHi";
    +    }
    +
    +    public String sayHiRequest2Wrapped(String in) {
    +        return "sayHi2";
    +    }
    +
    +}
    
  • systests/uncategorized/src/test/java/org/apache/cxf/systest/soap/RPCLitSoapActionGreeterImpl.java+40 0 added
    @@ -0,0 +1,40 @@
    +/**
    + * 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.cxf.systest.soap;
    +
    +import javax.jws.WebService;
    +import javax.jws.soap.SOAPBinding;
    +
    +import org.apache.hello_world_soap_action.WrappedGreeter;
    +
    +@WebService(endpointInterface = "org.apache.hello_world_soap_action.WrappedGreeter", 
    +serviceName = "WrappedSOAPService")
    +@SOAPBinding(style = SOAPBinding.Style.RPC)
    +public class RPCLitSoapActionGreeterImpl implements WrappedGreeter {
    +
    +    public String sayHiRequestWrapped(String in) {
    +        return "sayHi";
    +    }
    +
    +    public String sayHiRequest2Wrapped(String in) {
    +        return "sayHi2";
    +    }
    +
    +}
    
  • systests/uncategorized/src/test/java/org/apache/cxf/systest/soap/SoapActionTest.java+390 1 modified
    @@ -19,6 +19,8 @@
     
     package org.apache.cxf.systest.soap;
     
    +import javax.xml.ws.BindingProvider;
    +
     import org.apache.cxf.Bus;
     import org.apache.cxf.BusFactory;
     import org.apache.cxf.binding.soap.Soap12;
    @@ -27,6 +29,7 @@
     import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
     import org.apache.cxf.testutil.common.TestUtil;
     import org.apache.hello_world_soap_action.Greeter;
    +import org.apache.hello_world_soap_action.WrappedGreeter;
     import org.junit.AfterClass;
     import org.junit.Assert;
     import org.junit.BeforeClass;
    @@ -35,11 +38,20 @@
     public class SoapActionTest extends Assert {
         static final String PORT1 = TestUtil.getPortNumber(SoapActionTest.class, 1);
         static final String PORT2 = TestUtil.getPortNumber(SoapActionTest.class, 2);
    +    static final String PORT3 = TestUtil.getPortNumber(SoapActionTest.class, 3);
    +    static final String PORT4 = TestUtil.getPortNumber(SoapActionTest.class, 4);
    +    static final String PORT5 = TestUtil.getPortNumber(SoapActionTest.class, 5);
    +    static final String PORT6 = TestUtil.getPortNumber(SoapActionTest.class, 6);
    +    static final String PORT7 = TestUtil.getPortNumber(SoapActionTest.class, 7);
         
         static Bus bus;
         static String add11 = "http://localhost:" + PORT1 + "/test11";
         static String add12 = "http://localhost:" + PORT2 + "/test12";
    -
    +    static String add13 = "http://localhost:" + PORT3 + "/testWrapped";
    +    static String add14 = "http://localhost:" + PORT4 + "/testWrapped12";
    +    static String add15 = "http://localhost:" + PORT5 + "/testRPCLit";
    +    static String add16 = "http://localhost:" + PORT6 + "/testRPCEncoded";
    +    static String add17 = "http://localhost:" + PORT7 + "/testWrappedEncoded";
     
         @BeforeClass
         public static void createServers() throws Exception {
    @@ -58,7 +70,40 @@ public static void createServers() throws Exception {
             config.setVersion(Soap12.getInstance());
             sf.setBindingConfig(config);
             sf.create();
    +        
    +        sf = new JaxWsServerFactoryBean();
    +        sf.setServiceBean(new WrappedSoapActionGreeterImpl());
    +        sf.setAddress(add13);
    +        sf.setBus(bus);
    +        sf.create();
    +        
    +        sf = new JaxWsServerFactoryBean();
    +        sf.setServiceBean(new WrappedSoapActionGreeterImpl());
    +        sf.setAddress(add14);
    +        sf.setBus(bus);
    +        config.setVersion(Soap12.getInstance());
    +        sf.setBindingConfig(config);
    +        sf.create();
    +        
    +        sf = new JaxWsServerFactoryBean();
    +        sf.setServiceBean(new RPCLitSoapActionGreeterImpl());
    +        sf.setAddress(add15);
    +        sf.setBus(bus);
    +        sf.create();
    +        
    +        sf = new JaxWsServerFactoryBean();
    +        sf.setServiceBean(new RPCEncodedSoapActionGreeterImpl());
    +        sf.setAddress(add16);
    +        sf.setBus(bus);
    +        sf.create();
    +        
    +        sf = new JaxWsServerFactoryBean();
    +        sf.setServiceBean(new WrappedEncodedSoapActionGreeterImpl());
    +        sf.setAddress(add17);
    +        sf.setBus(bus);
    +        sf.create();
         }
    +    
         @AfterClass
         public static void shutdown() throws Exception {
             bus.shutdown(true);
    @@ -93,4 +138,348 @@ public void testSoap12Endpoint() throws Exception {
             assertEquals("sayHi", greeter.sayHi("test"));
             assertEquals("sayHi2", greeter.sayHi2("test"));
         }
    +    
    +    
    +    @Test
    +    public void testBareSoapActionSpoofing() throws Exception {
    +        JaxWsProxyFactoryBean pf = new JaxWsProxyFactoryBean();
    +        pf.setServiceClass(Greeter.class);
    +        pf.setAddress(add11);
    +        pf.setBus(bus);
    +        Greeter greeter = (Greeter) pf.create();
    +        
    +        assertEquals("sayHi", greeter.sayHi("test"));
    +        assertEquals("sayHi2", greeter.sayHi2("test"));        
    +        
    +        // Now test spoofing attack
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_2"
    +        );
    +        try {
    +            greeter.sayHi("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test the other operation
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_1"
    +        );
    +        try {
    +            greeter.sayHi2("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test a SOAP Action that does not exist in the binding
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_UNKNOWN"
    +        );
    +        try {
    +            greeter.sayHi("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +    }
    +    
    +    @Test
    +    public void testBareSoap12ActionSpoofing() throws Exception {
    +        JaxWsProxyFactoryBean pf = new JaxWsProxyFactoryBean();
    +        pf.setServiceClass(Greeter.class);
    +        pf.setAddress(add12);
    +        SoapBindingConfiguration config = new SoapBindingConfiguration();
    +        config.setVersion(Soap12.getInstance());
    +        pf.setBindingConfig(config);
    +        pf.setBus(bus);
    +        Greeter greeter = (Greeter) pf.create();
    +        
    +        assertEquals("sayHi", greeter.sayHi("test"));
    +        assertEquals("sayHi2", greeter.sayHi2("test"));        
    +        
    +        // Now test spoofing attack
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_2"
    +        );
    +        try {
    +            greeter.sayHi("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test the other operation
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_1"
    +        );
    +        try {
    +            greeter.sayHi2("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test a SOAP Action that does not exist in the binding
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_UNKNOWN"
    +        );
    +        try {
    +            greeter.sayHi("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +    }
    +    
    +    @Test
    +    public void testWrappedSoapActionSpoofing() throws Exception {
    +        JaxWsProxyFactoryBean pf = new JaxWsProxyFactoryBean();
    +        pf.setServiceClass(WrappedGreeter.class);
    +        pf.setAddress(add13);
    +        pf.setBus(bus);
    +        WrappedGreeter greeter = (WrappedGreeter) pf.create();
    +        
    +        assertEquals("sayHi", greeter.sayHiRequestWrapped("test"));
    +        assertEquals("sayHi2", greeter.sayHiRequest2Wrapped("test"));        
    +        
    +        // Now test spoofing attack
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_2"
    +        );
    +        try {
    +            greeter.sayHiRequestWrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test the other operation
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_1"
    +        );
    +        try {
    +            greeter.sayHiRequest2Wrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test a SOAP Action that does not exist in the binding
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_UNKNOWN"
    +        );
    +        try {
    +            greeter.sayHiRequestWrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +    }
    +    
    +    @Test
    +    public void testWrappedSoap12ActionSpoofing() throws Exception {
    +        JaxWsProxyFactoryBean pf = new JaxWsProxyFactoryBean();
    +        pf.setServiceClass(WrappedGreeter.class);
    +        pf.setAddress(add14);
    +        SoapBindingConfiguration config = new SoapBindingConfiguration();
    +        config.setVersion(Soap12.getInstance());
    +        pf.setBindingConfig(config);
    +        pf.setBus(bus);
    +        WrappedGreeter greeter = (WrappedGreeter) pf.create();
    +        
    +        assertEquals("sayHi", greeter.sayHiRequestWrapped("test"));
    +        assertEquals("sayHi2", greeter.sayHiRequest2Wrapped("test"));        
    +        
    +        // Now test spoofing attack
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_2"
    +        );
    +        try {
    +            greeter.sayHiRequestWrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test the other operation
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_1"
    +        );
    +        try {
    +            greeter.sayHiRequest2Wrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test a SOAP Action that does not exist in the binding
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_UNKNOWN"
    +        );
    +        try {
    +            greeter.sayHiRequestWrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +    }
    +    
    +    @Test
    +    public void testRPCLitSoapActionSpoofing() throws Exception {
    +        JaxWsProxyFactoryBean pf = new JaxWsProxyFactoryBean();
    +        pf.setServiceClass(WrappedGreeter.class);
    +        pf.setAddress(add15);
    +        pf.setBus(bus);
    +        WrappedGreeter greeter = (WrappedGreeter) pf.create();
    +        
    +        assertEquals("sayHi", greeter.sayHiRequestWrapped("test"));
    +        assertEquals("sayHi2", greeter.sayHiRequest2Wrapped("test"));        
    +        
    +        // Now test spoofing attack
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_2"
    +        );
    +        try {
    +            greeter.sayHiRequestWrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test the other operation
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_1"
    +        );
    +        try {
    +            greeter.sayHiRequest2Wrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test a SOAP Action that does not exist in the binding
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_UNKNOWN"
    +        );
    +        try {
    +            greeter.sayHiRequestWrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +    }
    +    
    +    @Test
    +    public void testRPCEncodedSoapActionSpoofing() throws Exception {
    +        JaxWsProxyFactoryBean pf = new JaxWsProxyFactoryBean();
    +        pf.setServiceClass(WrappedGreeter.class);
    +        pf.setAddress(add16);
    +        pf.setBus(bus);
    +        WrappedGreeter greeter = (WrappedGreeter) pf.create();
    +        
    +        assertEquals("sayHi", greeter.sayHiRequestWrapped("test"));
    +        assertEquals("sayHi2", greeter.sayHiRequest2Wrapped("test"));        
    +        
    +        // Now test spoofing attack
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_2"
    +        );
    +        try {
    +            greeter.sayHiRequestWrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test the other operation
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_1"
    +        );
    +        try {
    +            greeter.sayHiRequest2Wrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test a SOAP Action that does not exist in the binding
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_UNKNOWN"
    +        );
    +        try {
    +            greeter.sayHiRequestWrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +    }
    +    
    +    @Test
    +    public void testWrappedEncodedSoapActionSpoofing() throws Exception {
    +        JaxWsProxyFactoryBean pf = new JaxWsProxyFactoryBean();
    +        pf.setServiceClass(WrappedGreeter.class);
    +        pf.setAddress(add17);
    +        pf.setBus(bus);
    +        WrappedGreeter greeter = (WrappedGreeter) pf.create();
    +        
    +        assertEquals("sayHi", greeter.sayHiRequestWrapped("test"));
    +        assertEquals("sayHi2", greeter.sayHiRequest2Wrapped("test"));        
    +        
    +        // Now test spoofing attack
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_2"
    +        );
    +        try {
    +            greeter.sayHiRequestWrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test the other operation
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_1"
    +        );
    +        try {
    +            greeter.sayHiRequest2Wrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test a SOAP Action that does not exist in the binding
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_UNKNOWN"
    +        );
    +        try {
    +            greeter.sayHiRequestWrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +    }
    +    
     }
    
  • systests/uncategorized/src/test/java/org/apache/cxf/systest/soap/WrappedEncodedSoapActionGreeterImpl.java+40 0 added
    @@ -0,0 +1,40 @@
    +/**
    + * 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.cxf.systest.soap;
    +
    +import javax.jws.WebService;
    +import javax.jws.soap.SOAPBinding;
    +
    +import org.apache.hello_world_soap_action.WrappedGreeter;
    +
    +@WebService(endpointInterface = "org.apache.hello_world_soap_action.WrappedGreeter", 
    +            serviceName = "WrappedSOAPService")
    +@SOAPBinding(use = SOAPBinding.Use.ENCODED)
    +public class WrappedEncodedSoapActionGreeterImpl implements WrappedGreeter {
    +
    +    public String sayHiRequestWrapped(String in) {
    +        return "sayHi";
    +    }
    +
    +    public String sayHiRequest2Wrapped(String in) {
    +        return "sayHi2";
    +    }
    +
    +}
    
  • systests/uncategorized/src/test/java/org/apache/cxf/systest/soap/WrappedSoapActionGreeterImpl.java+38 0 added
    @@ -0,0 +1,38 @@
    +/**
    + * 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.cxf.systest.soap;
    +
    +import javax.jws.WebService;
    +
    +import org.apache.hello_world_soap_action.WrappedGreeter;
    +
    +@WebService(endpointInterface = "org.apache.hello_world_soap_action.WrappedGreeter", 
    +            serviceName = "WrappedSOAPService")
    +public class WrappedSoapActionGreeterImpl implements WrappedGreeter {
    +
    +    public String sayHiRequestWrapped(String in) {
    +        return "sayHi";
    +    }
    +
    +    public String sayHiRequest2Wrapped(String in) {
    +        return "sayHi2";
    +    }
    +
    +}
    
  • testutils/src/main/resources/wsdl/hello_world_soap_action.wsdl+115 0 modified
    @@ -26,6 +26,7 @@
       xmlns:jms="http://cxf.apache.org/transports/jms"
       xmlns:tns="http://apache.org/hello_world_soap_action"
       xmlns:x1="http://apache.org/hello_world_soap_action/types"
    +  xmlns:x2="http://apache.org/hello_world_soap_action/types/wrapped"
       xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
       targetNamespace="http://apache.org/hello_world_soap_action"
       name="HelloWorld">
    @@ -37,6 +38,36 @@
           <element name="text" type="xsd:string" />
           <element name="text2" type="xsd:string" />
         </schema>
    +    <xsd:schema targetNamespace="http://apache.org/hello_world_soap_action/types/wrapped">
    +            <xsd:element name="sayHiRequestWrapped">
    +                <xsd:complexType>
    +                    <xsd:sequence>
    +                        <xsd:element name="wrappedText" type="xsd:string" />
    +                    </xsd:sequence>
    +                </xsd:complexType>
    +            </xsd:element>
    +            <xsd:element name="sayHiResponseWrapped">
    +                <xsd:complexType>
    +                    <xsd:sequence>
    +                        <xsd:element name="wrappedTextResponse" type="xsd:string" />
    +                    </xsd:sequence>
    +                </xsd:complexType>
    +            </xsd:element>
    +            <xsd:element name="sayHiRequest2Wrapped">
    +                <xsd:complexType>
    +                    <xsd:sequence>
    +                        <xsd:element name="wrappedText" type="xsd:string" />
    +                    </xsd:sequence>
    +                </xsd:complexType>
    +            </xsd:element>
    +            <xsd:element name="sayHiResponse2Wrapped">
    +                <xsd:complexType>
    +                    <xsd:sequence>
    +                        <xsd:element name="wrappedTextResponse" type="xsd:string" />
    +                    </xsd:sequence>
    +                </xsd:complexType>
    +            </xsd:element>
    +        </xsd:schema>
       </wsdl:types>
       <wsdl:message name="sayHiRequest">
         <wsdl:part name="in" element="x1:text" />
    @@ -50,6 +81,19 @@
       <wsdl:message name="sayHiResponse2">
         <wsdl:part name="out" element="x1:text" />
       </wsdl:message>
    +  
    +  <wsdl:message name="sayHiRequestWrapped">
    +        <wsdl:part element="x2:sayHiRequestWrapped" name="parameters" />
    +  </wsdl:message>
    +  <wsdl:message name="sayHiResponseWrapped">
    +        <wsdl:part element="x2:sayHiResponseWrapped" name="parameters" />
    +  </wsdl:message>
    +  <wsdl:message name="sayHiRequest2Wrapped">
    +        <wsdl:part element="x2:sayHiRequest2Wrapped" name="parameters" />
    +  </wsdl:message>
    +  <wsdl:message name="sayHiResponse2Wrapped">
    +        <wsdl:part element="x2:sayHiResponse2Wrapped" name="parameters" />
    +  </wsdl:message>
     
       <wsdl:portType name="Greeter">
         <wsdl:operation name="sayHi">
    @@ -63,6 +107,19 @@
         </wsdl:operation>
     
       </wsdl:portType>
    +  
    +  <wsdl:portType name="WrappedGreeter">
    +        <wsdl:operation name="sayHiRequestWrapped">
    +            <wsdl:input message="tns:sayHiRequestWrapped" />
    +            <wsdl:output message="tns:sayHiResponseWrapped" />
    +        </wsdl:operation>
    +        
    +        <wsdl:operation name="sayHiRequest2Wrapped">
    +            <wsdl:input message="tns:sayHiRequest2Wrapped" />
    +            <wsdl:output message="tns:sayHiResponse2Wrapped" />
    +        </wsdl:operation>
    +  </wsdl:portType>
    +  
       <wsdl:binding name="Greeter_SOAPBinding" type="tns:Greeter">
         <soap:binding style="document"
           transport="http://schemas.xmlsoap.org/soap/http" />
    @@ -86,6 +143,7 @@
         </wsdl:operation>
     
       </wsdl:binding>
    +  
       <wsdl:binding name="Greeter_SOAP12Binding" type="tns:Greeter">
         <soap12:binding style="document"
           transport="http://www.w3.org/2003/05/soap/bindings/HTTP/" />
    @@ -109,6 +167,53 @@
         </wsdl:operation>
         
       </wsdl:binding>
    +  
    +  <wsdl:binding name="Greeter_WrappedSOAPBinding" type="tns:WrappedGreeter">
    +        <soap:binding style="document"
    +            transport="http://schemas.xmlsoap.org/soap/http" />
    +        <wsdl:operation name="sayHiRequestWrapped">
    +            <soap:operation soapAction="SAY_HI_1" />
    +            <wsdl:input>
    +                <soap:body use="literal" />
    +            </wsdl:input>
    +            <wsdl:output>
    +                <soap:body use="literal" />
    +            </wsdl:output>
    +        </wsdl:operation>
    +        <wsdl:operation name="sayHiRequest2Wrapped">
    +            <soap:operation soapAction="SAY_HI_2" />
    +            <wsdl:input>
    +                <soap:body use="literal" />
    +            </wsdl:input>
    +            <wsdl:output>
    +                <soap:body use="literal" />
    +            </wsdl:output>
    +        </wsdl:operation>
    +  </wsdl:binding>     
    +  
    +  <wsdl:binding name="Greeter_WrappedSOAP12Binding" type="tns:WrappedGreeter">
    +        <soap12:binding style="document"
    +            transport="http://www.w3.org/2003/05/soap/bindings/HTTP/" />
    +        <wsdl:operation name="sayHiRequestWrapped">
    +            <soap12:operation soapAction="SAY_HI_1" />
    +            <wsdl:input>
    +                <soap12:body use="literal" />
    +            </wsdl:input>
    +            <wsdl:output>
    +                <soap12:body use="literal" />
    +            </wsdl:output>
    +        </wsdl:operation>
    +        <wsdl:operation name="sayHiRequest2Wrapped">
    +            <soap12:operation soapAction="SAY_HI_2" />
    +            <wsdl:input>
    +                <soap12:body use="literal" />
    +            </wsdl:input>
    +            <wsdl:output>
    +                <soap12:body use="literal" />
    +            </wsdl:output>
    +        </wsdl:operation>
    +  </wsdl:binding>     
    +  
       <wsdl:service name="SOAPService">
         <wsdl:port name="SoapPort" binding="tns:Greeter_SOAPBinding">
           <soap:address
    @@ -121,4 +226,14 @@
             location="http://localhost:9001/SOAPDocLitService/Soap12Port" />
         </wsdl:port>
       </wsdl:service>
    +  <wsdl:service name="WrappedSOAPService">
    +      <wsdl:port name="WrappedSoapPort" binding="tns:Greeter_WrappedSOAPBinding">
    +            <soap:address location="http://localhost:9001/SOAPDocLitService/WrappedSoapPort" />
    +      </wsdl:port>
    +  </wsdl:service>
    +  <wsdl:service name="WrappedSOAP12Service">
    +      <wsdl:port name="WrappedSoap12Port" binding="tns:Greeter_WrappedSOAP12Binding">
    +            <soap:address location="http://localhost:9001/SOAPDocLitService/WrappedSoap12Port" />
    +      </wsdl:port>
    +  </wsdl:service>
     </wsdl:definitions>
    
7230648f9657

Merged revisions 1368559 via git cherry-pick from

https://github.com/apache/cxfColm O HeigeartaighAug 2, 2012via ghsa
10 files changed · +760 21
  • rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/Messages.properties+1 0 modified
    @@ -31,3 +31,4 @@ INVALID_11_VERSION=A SOAP 1.2 message is not valid when sent to a SOAP 1.1 only
     NO_NAMESPACE=No namespace on "{0}" element.
     BP_2211_RPCLIT_CANNOT_BE_NULL=Cannot write part {0}. RPC/Literal parts cannot be null. (WS-I BP R2211)
     UNKNOWN_RPC_LIT_PART=Found element {0} but could not find matching RPC/Literal part
    +SOAP_ACTION_MISMATCH=The given SOAPAction {0} does not match an operation.
    
  • rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/SoapActionInInterceptor.java+52 14 modified
    @@ -22,12 +22,14 @@
     import java.util.Collection;
     import java.util.List;
     import java.util.Map;
    +import java.util.logging.Logger;
     
     import org.apache.cxf.binding.soap.Soap11;
     import org.apache.cxf.binding.soap.Soap12;
     import org.apache.cxf.binding.soap.SoapBindingConstants;
     import org.apache.cxf.binding.soap.SoapMessage;
     import org.apache.cxf.binding.soap.model.SoapOperationInfo;
    +import org.apache.cxf.common.logging.LogUtils;
     import org.apache.cxf.common.util.StringUtils;
     import org.apache.cxf.endpoint.Endpoint;
     import org.apache.cxf.helpers.CastUtils;
    @@ -40,6 +42,8 @@
     
     public class SoapActionInInterceptor extends AbstractSoapInterceptor {
         
    +    private static final Logger LOG = LogUtils.getL7dLogger(SoapActionInInterceptor.class);
    +    
         public SoapActionInInterceptor() {
             super(Phase.READ);
             addAfter(ReadHeadersInterceptor.class.getName());
    @@ -91,6 +95,10 @@ public static String getSoapAction(Message m) {
         }
         
         public void handleMessage(SoapMessage message) throws Fault {
    +        if (isRequestor(message)) {
    +            return;
    +        }
    +        
             String action = getSoapAction(message);
             if (!StringUtils.isEmpty(action)) {
                 getAndSetOperation(message, action);
    @@ -108,24 +116,54 @@ private void getAndSetOperation(SoapMessage message, String action) {
             
             BindingOperationInfo bindingOp = null;
             
    -        Collection<BindingOperationInfo> bops = ep.getBinding().getBindingInfo().getOperations();
    -        if (bops == null) {
    -            return;
    -        }
    -        for (BindingOperationInfo boi : bops) {
    -            SoapOperationInfo soi = (SoapOperationInfo) boi.getExtensor(SoapOperationInfo.class);
    -            if (soi != null && action.equals(soi.getAction())) {
    -                if (bindingOp != null) {
    -                    //more than one op with the same action, will need to parse normally
    -                    return;
    +        Collection<BindingOperationInfo> bops = ep.getEndpointInfo()
    +            .getBinding().getOperations();
    +        if (bops != null) {
    +            for (BindingOperationInfo boi : bops) {
    +                SoapOperationInfo soi = boi.getExtensor(SoapOperationInfo.class);
    +                if (soi != null && action.equals(soi.getAction())) {
    +                    if (bindingOp != null) {
    +                        //more than one op with the same action, will need to parse normally
    +                        return;
    +                    }
    +                    bindingOp = boi;
                     }
    -                bindingOp = boi;
                 }
             }
    -        if (bindingOp != null) {
    -            ex.put(BindingOperationInfo.class, bindingOp);
    -            ex.put(OperationInfo.class, bindingOp.getOperationInfo());
    +        
    +        if (bindingOp == null) {
    +            //we didn't match the an operation, we'll try again later to make
    +            //sure the incoming message did end up matching an operation.
    +            //This could occur in some cases like WS-RM and WS-SecConv that will
    +            //intercept the message with a new endpoint/operation
    +            message.getInterceptorChain().add(new SoapActionInAttemptTwoInterceptor());
    +            return;
    +        }
    +
    +        ex.put(BindingOperationInfo.class, bindingOp);
    +        ex.put(OperationInfo.class, bindingOp.getOperationInfo());
    +    }
    +    
    +    public static class SoapActionInAttemptTwoInterceptor extends AbstractSoapInterceptor {
    +        public SoapActionInAttemptTwoInterceptor() {
    +            super(Phase.PRE_LOGICAL);
    +        }
    +        public void handleMessage(SoapMessage message) throws Fault {
    +            BindingOperationInfo boi = message.getExchange().getBindingOperationInfo();
    +            if (boi == null) {
    +                return;
    +            }
    +            String action = getSoapAction(message);
    +            if (StringUtils.isEmpty(action)) {
    +                return;
    +            }
    +            SoapOperationInfo soi = boi.getExtensor(SoapOperationInfo.class);
    +            if (soi == null || action.equals(soi.getAction())) {
    +                return;
    +            }
    +            throw new Fault("SOAP_ACTION_MISMATCH", LOG, null, action);
             }
         }
     
    +
     }
    
  • rt/core/src/main/java/org/apache/cxf/interceptor/DocLiteralInInterceptor.java+43 6 modified
    @@ -192,12 +192,11 @@ public void handleMessage(Message message) {
                         } else {
                             p = findMessagePart(exchange, operations, elName, client, paramNum, message);
                         }
    -    
    -                    if (p == null) {
    -                        throw new Fault(new org.apache.cxf.common.i18n.Message("NO_PART_FOUND", LOG, elName),
    -                                        Fault.FAULT_CODE_CLIENT);
    -                    }
    -    
    +                    
    +                    //Make sure the elName found on the wire is actually OK for 
    +                    //the purpose we need it
    +                    validatePart(p, elName, si);
    +
                         o = dr.read(p, xmlReader);
                         if (Boolean.TRUE.equals(si.getProperty("soap.force.doclit.bare")) 
                             && parameters.isEmpty()) {
    @@ -224,6 +223,44 @@ public void handleMessage(Message message) {
             }
         }
         
    +    private void validatePart(MessagePartInfo p, QName elName, ServiceInfo si) {
    +        if (p == null) {
    +            throw new Fault(new org.apache.cxf.common.i18n.Message("NO_PART_FOUND", LOG, elName),
    +                            Fault.FAULT_CODE_CLIENT);
    +
    +        }
    +
    +        Boolean synth = Boolean.FALSE;
    +        if (p.getMessageInfo() != null && p.getMessageInfo().getOperation() != null) {
    +            OperationInfo op = p.getMessageInfo().getOperation();
    +            Boolean b = (Boolean)op.getProperty("operation.is.synthetic");
    +            if (b != null) {
    +                synth = b;
    +            }
    +        }
    +        if (si != null && Boolean.TRUE.equals(si.getProperty("soap.force.doclit.bare"))) {
    +            // something like a Provider service or similar that is forcing a
    +            // doc/lit/bare on an endpoint that may not really be doc/lit/bare.  
    +            // we need to just let these through per spec so the endpoint
    +            // can process it
    +            synth = true;
    +        }
    +        if (p.isElement()) {
    +            if (p.getConcreteName() != null
    +                && !elName.equals(p.getConcreteName())
    +                && !Boolean.TRUE.equals(synth)) {
    +                throw new Fault("UNEXPECTED_ELEMENT", LOG, null, elName,
    +                                p.getConcreteName());
    +            }
    +        } else {
    +            if (!(elName.equals(p.getName()) || elName.equals(p.getConcreteName()))
    +                && !Boolean.TRUE.equals(synth)) {
    +                throw new Fault("UNEXPECTED_ELEMENT", LOG, null, elName,
    +                                p.getConcreteName());
    +            }
    +        }
    +    }
    +    
         private void getPara(DepthXMLStreamReader xmlReader,
                              DataReader<XMLStreamReader> dr,
                              MessageContentsList parameters,
    
  • rt/core/src/main/java/org/apache/cxf/interceptor/Messages.properties+1 0 modified
    @@ -40,4 +40,5 @@ COULD_NOT_FIND_SEICLASS=Could not find the class: {0}
     EXCEPTION_WHILE_WRITING_FAULT = Exception occurred while writing fault.
     EXCEPTION_WHILE_CREATING_EXCEPTION = Exception occurred while creating exception: {0}
     UNEXPECTED_WRAPPER_ELEMENT = Unexpected wrapper element {0} found.   Expected {1}.
    +UNEXPECTED_ELEMENT = Unexpected element {0} found.   Expected {1}.
      
    
  • systests/uncategorized/src/test/java/org/apache/cxf/systest/soap/RPCEncodedSoapActionGreeterImpl.java+40 0 added
    @@ -0,0 +1,40 @@
    +/**
    + * 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.cxf.systest.soap;
    +
    +import javax.jws.WebService;
    +import javax.jws.soap.SOAPBinding;
    +
    +import org.apache.hello_world_soap_action.WrappedGreeter;
    +
    +@WebService(endpointInterface = "org.apache.hello_world_soap_action.WrappedGreeter", 
    +serviceName = "WrappedSOAPService")
    +@SOAPBinding(style = SOAPBinding.Style.RPC, use = SOAPBinding.Use.ENCODED)
    +public class RPCEncodedSoapActionGreeterImpl implements WrappedGreeter {
    +
    +    public String sayHiRequestWrapped(String in) {
    +        return "sayHi";
    +    }
    +
    +    public String sayHiRequest2Wrapped(String in) {
    +        return "sayHi2";
    +    }
    +
    +}
    
  • systests/uncategorized/src/test/java/org/apache/cxf/systest/soap/RPCLitSoapActionGreeterImpl.java+40 0 added
    @@ -0,0 +1,40 @@
    +/**
    + * 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.cxf.systest.soap;
    +
    +import javax.jws.WebService;
    +import javax.jws.soap.SOAPBinding;
    +
    +import org.apache.hello_world_soap_action.WrappedGreeter;
    +
    +@WebService(endpointInterface = "org.apache.hello_world_soap_action.WrappedGreeter", 
    +serviceName = "WrappedSOAPService")
    +@SOAPBinding(style = SOAPBinding.Style.RPC)
    +public class RPCLitSoapActionGreeterImpl implements WrappedGreeter {
    +
    +    public String sayHiRequestWrapped(String in) {
    +        return "sayHi";
    +    }
    +
    +    public String sayHiRequest2Wrapped(String in) {
    +        return "sayHi2";
    +    }
    +
    +}
    
  • systests/uncategorized/src/test/java/org/apache/cxf/systest/soap/SoapActionTest.java+390 1 modified
    @@ -19,6 +19,8 @@
     
     package org.apache.cxf.systest.soap;
     
    +import javax.xml.ws.BindingProvider;
    +
     import org.apache.cxf.Bus;
     import org.apache.cxf.BusFactory;
     import org.apache.cxf.binding.soap.Soap12;
    @@ -27,6 +29,7 @@
     import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
     import org.apache.cxf.testutil.common.TestUtil;
     import org.apache.hello_world_soap_action.Greeter;
    +import org.apache.hello_world_soap_action.WrappedGreeter;
     import org.junit.AfterClass;
     import org.junit.Assert;
     import org.junit.BeforeClass;
    @@ -35,11 +38,20 @@
     public class SoapActionTest extends Assert {
         static final String PORT1 = TestUtil.getPortNumber(SoapActionTest.class, 1);
         static final String PORT2 = TestUtil.getPortNumber(SoapActionTest.class, 2);
    +    static final String PORT3 = TestUtil.getPortNumber(SoapActionTest.class, 3);
    +    static final String PORT4 = TestUtil.getPortNumber(SoapActionTest.class, 4);
    +    static final String PORT5 = TestUtil.getPortNumber(SoapActionTest.class, 5);
    +    static final String PORT6 = TestUtil.getPortNumber(SoapActionTest.class, 6);
    +    static final String PORT7 = TestUtil.getPortNumber(SoapActionTest.class, 7);
         
         static Bus bus;
         static String add11 = "http://localhost:" + PORT1 + "/test11";
         static String add12 = "http://localhost:" + PORT2 + "/test12";
    -
    +    static String add13 = "http://localhost:" + PORT3 + "/testWrapped";
    +    static String add14 = "http://localhost:" + PORT4 + "/testWrapped12";
    +    static String add15 = "http://localhost:" + PORT5 + "/testRPCLit";
    +    static String add16 = "http://localhost:" + PORT6 + "/testRPCEncoded";
    +    static String add17 = "http://localhost:" + PORT7 + "/testWrappedEncoded";
     
         @BeforeClass
         public static void createServers() throws Exception {
    @@ -58,7 +70,40 @@ public static void createServers() throws Exception {
             config.setVersion(Soap12.getInstance());
             sf.setBindingConfig(config);
             sf.create();
    +        
    +        sf = new JaxWsServerFactoryBean();
    +        sf.setServiceBean(new WrappedSoapActionGreeterImpl());
    +        sf.setAddress(add13);
    +        sf.setBus(bus);
    +        sf.create();
    +        
    +        sf = new JaxWsServerFactoryBean();
    +        sf.setServiceBean(new WrappedSoapActionGreeterImpl());
    +        sf.setAddress(add14);
    +        sf.setBus(bus);
    +        config.setVersion(Soap12.getInstance());
    +        sf.setBindingConfig(config);
    +        sf.create();
    +        
    +        sf = new JaxWsServerFactoryBean();
    +        sf.setServiceBean(new RPCLitSoapActionGreeterImpl());
    +        sf.setAddress(add15);
    +        sf.setBus(bus);
    +        sf.create();
    +        
    +        sf = new JaxWsServerFactoryBean();
    +        sf.setServiceBean(new RPCEncodedSoapActionGreeterImpl());
    +        sf.setAddress(add16);
    +        sf.setBus(bus);
    +        sf.create();
    +        
    +        sf = new JaxWsServerFactoryBean();
    +        sf.setServiceBean(new WrappedEncodedSoapActionGreeterImpl());
    +        sf.setAddress(add17);
    +        sf.setBus(bus);
    +        sf.create();
         }
    +    
         @AfterClass
         public static void shutdown() throws Exception {
             bus.shutdown(true);
    @@ -93,4 +138,348 @@ public void testSoap12Endpoint() throws Exception {
             assertEquals("sayHi", greeter.sayHi("test"));
             assertEquals("sayHi2", greeter.sayHi2("test"));
         }
    +    
    +    
    +    @Test
    +    public void testBareSoapActionSpoofing() throws Exception {
    +        JaxWsProxyFactoryBean pf = new JaxWsProxyFactoryBean();
    +        pf.setServiceClass(Greeter.class);
    +        pf.setAddress(add11);
    +        pf.setBus(bus);
    +        Greeter greeter = (Greeter) pf.create();
    +        
    +        assertEquals("sayHi", greeter.sayHi("test"));
    +        assertEquals("sayHi2", greeter.sayHi2("test"));        
    +        
    +        // Now test spoofing attack
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_2"
    +        );
    +        try {
    +            greeter.sayHi("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test the other operation
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_1"
    +        );
    +        try {
    +            greeter.sayHi2("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test a SOAP Action that does not exist in the binding
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_UNKNOWN"
    +        );
    +        try {
    +            greeter.sayHi("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +    }
    +    
    +    @Test
    +    public void testBareSoap12ActionSpoofing() throws Exception {
    +        JaxWsProxyFactoryBean pf = new JaxWsProxyFactoryBean();
    +        pf.setServiceClass(Greeter.class);
    +        pf.setAddress(add12);
    +        SoapBindingConfiguration config = new SoapBindingConfiguration();
    +        config.setVersion(Soap12.getInstance());
    +        pf.setBindingConfig(config);
    +        pf.setBus(bus);
    +        Greeter greeter = (Greeter) pf.create();
    +        
    +        assertEquals("sayHi", greeter.sayHi("test"));
    +        assertEquals("sayHi2", greeter.sayHi2("test"));        
    +        
    +        // Now test spoofing attack
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_2"
    +        );
    +        try {
    +            greeter.sayHi("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test the other operation
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_1"
    +        );
    +        try {
    +            greeter.sayHi2("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test a SOAP Action that does not exist in the binding
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_UNKNOWN"
    +        );
    +        try {
    +            greeter.sayHi("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +    }
    +    
    +    @Test
    +    public void testWrappedSoapActionSpoofing() throws Exception {
    +        JaxWsProxyFactoryBean pf = new JaxWsProxyFactoryBean();
    +        pf.setServiceClass(WrappedGreeter.class);
    +        pf.setAddress(add13);
    +        pf.setBus(bus);
    +        WrappedGreeter greeter = (WrappedGreeter) pf.create();
    +        
    +        assertEquals("sayHi", greeter.sayHiRequestWrapped("test"));
    +        assertEquals("sayHi2", greeter.sayHiRequest2Wrapped("test"));        
    +        
    +        // Now test spoofing attack
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_2"
    +        );
    +        try {
    +            greeter.sayHiRequestWrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test the other operation
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_1"
    +        );
    +        try {
    +            greeter.sayHiRequest2Wrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test a SOAP Action that does not exist in the binding
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_UNKNOWN"
    +        );
    +        try {
    +            greeter.sayHiRequestWrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +    }
    +    
    +    @Test
    +    public void testWrappedSoap12ActionSpoofing() throws Exception {
    +        JaxWsProxyFactoryBean pf = new JaxWsProxyFactoryBean();
    +        pf.setServiceClass(WrappedGreeter.class);
    +        pf.setAddress(add14);
    +        SoapBindingConfiguration config = new SoapBindingConfiguration();
    +        config.setVersion(Soap12.getInstance());
    +        pf.setBindingConfig(config);
    +        pf.setBus(bus);
    +        WrappedGreeter greeter = (WrappedGreeter) pf.create();
    +        
    +        assertEquals("sayHi", greeter.sayHiRequestWrapped("test"));
    +        assertEquals("sayHi2", greeter.sayHiRequest2Wrapped("test"));        
    +        
    +        // Now test spoofing attack
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_2"
    +        );
    +        try {
    +            greeter.sayHiRequestWrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test the other operation
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_1"
    +        );
    +        try {
    +            greeter.sayHiRequest2Wrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test a SOAP Action that does not exist in the binding
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_UNKNOWN"
    +        );
    +        try {
    +            greeter.sayHiRequestWrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +    }
    +    
    +    @Test
    +    public void testRPCLitSoapActionSpoofing() throws Exception {
    +        JaxWsProxyFactoryBean pf = new JaxWsProxyFactoryBean();
    +        pf.setServiceClass(WrappedGreeter.class);
    +        pf.setAddress(add15);
    +        pf.setBus(bus);
    +        WrappedGreeter greeter = (WrappedGreeter) pf.create();
    +        
    +        assertEquals("sayHi", greeter.sayHiRequestWrapped("test"));
    +        assertEquals("sayHi2", greeter.sayHiRequest2Wrapped("test"));        
    +        
    +        // Now test spoofing attack
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_2"
    +        );
    +        try {
    +            greeter.sayHiRequestWrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test the other operation
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_1"
    +        );
    +        try {
    +            greeter.sayHiRequest2Wrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test a SOAP Action that does not exist in the binding
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_UNKNOWN"
    +        );
    +        try {
    +            greeter.sayHiRequestWrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +    }
    +    
    +    @Test
    +    public void testRPCEncodedSoapActionSpoofing() throws Exception {
    +        JaxWsProxyFactoryBean pf = new JaxWsProxyFactoryBean();
    +        pf.setServiceClass(WrappedGreeter.class);
    +        pf.setAddress(add16);
    +        pf.setBus(bus);
    +        WrappedGreeter greeter = (WrappedGreeter) pf.create();
    +        
    +        assertEquals("sayHi", greeter.sayHiRequestWrapped("test"));
    +        assertEquals("sayHi2", greeter.sayHiRequest2Wrapped("test"));        
    +        
    +        // Now test spoofing attack
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_2"
    +        );
    +        try {
    +            greeter.sayHiRequestWrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test the other operation
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_1"
    +        );
    +        try {
    +            greeter.sayHiRequest2Wrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test a SOAP Action that does not exist in the binding
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_UNKNOWN"
    +        );
    +        try {
    +            greeter.sayHiRequestWrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +    }
    +    
    +    @Test
    +    public void testWrappedEncodedSoapActionSpoofing() throws Exception {
    +        JaxWsProxyFactoryBean pf = new JaxWsProxyFactoryBean();
    +        pf.setServiceClass(WrappedGreeter.class);
    +        pf.setAddress(add17);
    +        pf.setBus(bus);
    +        WrappedGreeter greeter = (WrappedGreeter) pf.create();
    +        
    +        assertEquals("sayHi", greeter.sayHiRequestWrapped("test"));
    +        assertEquals("sayHi2", greeter.sayHiRequest2Wrapped("test"));        
    +        
    +        // Now test spoofing attack
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_2"
    +        );
    +        try {
    +            greeter.sayHiRequestWrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test the other operation
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_1"
    +        );
    +        try {
    +            greeter.sayHiRequest2Wrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test a SOAP Action that does not exist in the binding
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_UNKNOWN"
    +        );
    +        try {
    +            greeter.sayHiRequestWrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +    }
    +    
     }
    
  • systests/uncategorized/src/test/java/org/apache/cxf/systest/soap/WrappedEncodedSoapActionGreeterImpl.java+40 0 added
    @@ -0,0 +1,40 @@
    +/**
    + * 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.cxf.systest.soap;
    +
    +import javax.jws.WebService;
    +import javax.jws.soap.SOAPBinding;
    +
    +import org.apache.hello_world_soap_action.WrappedGreeter;
    +
    +@WebService(endpointInterface = "org.apache.hello_world_soap_action.WrappedGreeter", 
    +            serviceName = "WrappedSOAPService")
    +@SOAPBinding(use = SOAPBinding.Use.ENCODED)
    +public class WrappedEncodedSoapActionGreeterImpl implements WrappedGreeter {
    +
    +    public String sayHiRequestWrapped(String in) {
    +        return "sayHi";
    +    }
    +
    +    public String sayHiRequest2Wrapped(String in) {
    +        return "sayHi2";
    +    }
    +
    +}
    
  • systests/uncategorized/src/test/java/org/apache/cxf/systest/soap/WrappedSoapActionGreeterImpl.java+38 0 added
    @@ -0,0 +1,38 @@
    +/**
    + * 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.cxf.systest.soap;
    +
    +import javax.jws.WebService;
    +
    +import org.apache.hello_world_soap_action.WrappedGreeter;
    +
    +@WebService(endpointInterface = "org.apache.hello_world_soap_action.WrappedGreeter", 
    +            serviceName = "WrappedSOAPService")
    +public class WrappedSoapActionGreeterImpl implements WrappedGreeter {
    +
    +    public String sayHiRequestWrapped(String in) {
    +        return "sayHi";
    +    }
    +
    +    public String sayHiRequest2Wrapped(String in) {
    +        return "sayHi2";
    +    }
    +
    +}
    
  • testutils/src/main/resources/wsdl/hello_world_soap_action.wsdl+115 0 modified
    @@ -26,6 +26,7 @@
       xmlns:jms="http://cxf.apache.org/transports/jms"
       xmlns:tns="http://apache.org/hello_world_soap_action"
       xmlns:x1="http://apache.org/hello_world_soap_action/types"
    +  xmlns:x2="http://apache.org/hello_world_soap_action/types/wrapped"
       xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
       targetNamespace="http://apache.org/hello_world_soap_action"
       name="HelloWorld">
    @@ -37,6 +38,36 @@
           <element name="text" type="xsd:string" />
           <element name="text2" type="xsd:string" />
         </schema>
    +    <xsd:schema targetNamespace="http://apache.org/hello_world_soap_action/types/wrapped">
    +            <xsd:element name="sayHiRequestWrapped">
    +                <xsd:complexType>
    +                    <xsd:sequence>
    +                        <xsd:element name="wrappedText" type="xsd:string" />
    +                    </xsd:sequence>
    +                </xsd:complexType>
    +            </xsd:element>
    +            <xsd:element name="sayHiResponseWrapped">
    +                <xsd:complexType>
    +                    <xsd:sequence>
    +                        <xsd:element name="wrappedTextResponse" type="xsd:string" />
    +                    </xsd:sequence>
    +                </xsd:complexType>
    +            </xsd:element>
    +            <xsd:element name="sayHiRequest2Wrapped">
    +                <xsd:complexType>
    +                    <xsd:sequence>
    +                        <xsd:element name="wrappedText" type="xsd:string" />
    +                    </xsd:sequence>
    +                </xsd:complexType>
    +            </xsd:element>
    +            <xsd:element name="sayHiResponse2Wrapped">
    +                <xsd:complexType>
    +                    <xsd:sequence>
    +                        <xsd:element name="wrappedTextResponse" type="xsd:string" />
    +                    </xsd:sequence>
    +                </xsd:complexType>
    +            </xsd:element>
    +        </xsd:schema>
       </wsdl:types>
       <wsdl:message name="sayHiRequest">
         <wsdl:part name="in" element="x1:text" />
    @@ -50,6 +81,19 @@
       <wsdl:message name="sayHiResponse2">
         <wsdl:part name="out" element="x1:text" />
       </wsdl:message>
    +  
    +  <wsdl:message name="sayHiRequestWrapped">
    +        <wsdl:part element="x2:sayHiRequestWrapped" name="parameters" />
    +  </wsdl:message>
    +  <wsdl:message name="sayHiResponseWrapped">
    +        <wsdl:part element="x2:sayHiResponseWrapped" name="parameters" />
    +  </wsdl:message>
    +  <wsdl:message name="sayHiRequest2Wrapped">
    +        <wsdl:part element="x2:sayHiRequest2Wrapped" name="parameters" />
    +  </wsdl:message>
    +  <wsdl:message name="sayHiResponse2Wrapped">
    +        <wsdl:part element="x2:sayHiResponse2Wrapped" name="parameters" />
    +  </wsdl:message>
     
       <wsdl:portType name="Greeter">
         <wsdl:operation name="sayHi">
    @@ -63,6 +107,19 @@
         </wsdl:operation>
     
       </wsdl:portType>
    +  
    +  <wsdl:portType name="WrappedGreeter">
    +        <wsdl:operation name="sayHiRequestWrapped">
    +            <wsdl:input message="tns:sayHiRequestWrapped" />
    +            <wsdl:output message="tns:sayHiResponseWrapped" />
    +        </wsdl:operation>
    +        
    +        <wsdl:operation name="sayHiRequest2Wrapped">
    +            <wsdl:input message="tns:sayHiRequest2Wrapped" />
    +            <wsdl:output message="tns:sayHiResponse2Wrapped" />
    +        </wsdl:operation>
    +  </wsdl:portType>
    +  
       <wsdl:binding name="Greeter_SOAPBinding" type="tns:Greeter">
         <soap:binding style="document"
           transport="http://schemas.xmlsoap.org/soap/http" />
    @@ -86,6 +143,7 @@
         </wsdl:operation>
     
       </wsdl:binding>
    +  
       <wsdl:binding name="Greeter_SOAP12Binding" type="tns:Greeter">
         <soap12:binding style="document"
           transport="http://www.w3.org/2003/05/soap/bindings/HTTP/" />
    @@ -109,6 +167,53 @@
         </wsdl:operation>
         
       </wsdl:binding>
    +  
    +  <wsdl:binding name="Greeter_WrappedSOAPBinding" type="tns:WrappedGreeter">
    +        <soap:binding style="document"
    +            transport="http://schemas.xmlsoap.org/soap/http" />
    +        <wsdl:operation name="sayHiRequestWrapped">
    +            <soap:operation soapAction="SAY_HI_1" />
    +            <wsdl:input>
    +                <soap:body use="literal" />
    +            </wsdl:input>
    +            <wsdl:output>
    +                <soap:body use="literal" />
    +            </wsdl:output>
    +        </wsdl:operation>
    +        <wsdl:operation name="sayHiRequest2Wrapped">
    +            <soap:operation soapAction="SAY_HI_2" />
    +            <wsdl:input>
    +                <soap:body use="literal" />
    +            </wsdl:input>
    +            <wsdl:output>
    +                <soap:body use="literal" />
    +            </wsdl:output>
    +        </wsdl:operation>
    +  </wsdl:binding>     
    +  
    +  <wsdl:binding name="Greeter_WrappedSOAP12Binding" type="tns:WrappedGreeter">
    +        <soap12:binding style="document"
    +            transport="http://www.w3.org/2003/05/soap/bindings/HTTP/" />
    +        <wsdl:operation name="sayHiRequestWrapped">
    +            <soap12:operation soapAction="SAY_HI_1" />
    +            <wsdl:input>
    +                <soap12:body use="literal" />
    +            </wsdl:input>
    +            <wsdl:output>
    +                <soap12:body use="literal" />
    +            </wsdl:output>
    +        </wsdl:operation>
    +        <wsdl:operation name="sayHiRequest2Wrapped">
    +            <soap12:operation soapAction="SAY_HI_2" />
    +            <wsdl:input>
    +                <soap12:body use="literal" />
    +            </wsdl:input>
    +            <wsdl:output>
    +                <soap12:body use="literal" />
    +            </wsdl:output>
    +        </wsdl:operation>
    +  </wsdl:binding>     
    +  
       <wsdl:service name="SOAPService">
         <wsdl:port name="SoapPort" binding="tns:Greeter_SOAPBinding">
           <soap:address
    @@ -121,4 +226,14 @@
             location="http://localhost:9001/SOAPDocLitService/Soap12Port" />
         </wsdl:port>
       </wsdl:service>
    +  <wsdl:service name="WrappedSOAPService">
    +      <wsdl:port name="WrappedSoapPort" binding="tns:Greeter_WrappedSOAPBinding">
    +            <soap:address location="http://localhost:9001/SOAPDocLitService/WrappedSoapPort" />
    +      </wsdl:port>
    +  </wsdl:service>
    +  <wsdl:service name="WrappedSOAP12Service">
    +      <wsdl:port name="WrappedSoap12Port" binding="tns:Greeter_WrappedSOAP12Binding">
    +            <soap:address location="http://localhost:9001/SOAPDocLitService/WrappedSoap12Port" />
    +      </wsdl:port>
    +  </wsdl:service>
     </wsdl:definitions>
    
878fe37f0b09

Merged revisions 1368559 via git cherry-pick from

https://github.com/apache/cxfColm O HeigeartaighAug 2, 2012via ghsa
10 files changed · +759 20
  • api/src/main/java/org/apache/cxf/interceptor/DocLiteralInInterceptor.java+43 6 modified
    @@ -191,12 +191,11 @@ public void handleMessage(Message message) {
                         } else {
                             p = findMessagePart(exchange, operations, elName, client, paramNum, message);
                         }
    -    
    -                    if (p == null) {
    -                        throw new Fault(new org.apache.cxf.common.i18n.Message("NO_PART_FOUND", LOG, elName),
    -                                        Fault.FAULT_CODE_CLIENT);
    -                    }
    -    
    +                    
    +                    //Make sure the elName found on the wire is actually OK for 
    +                    //the purpose we need it
    +                    validatePart(p, elName, si);
    +
                         o = dr.read(p, xmlReader);
                         if (Boolean.TRUE.equals(si.getProperty("soap.force.doclit.bare")) 
                             && parameters.isEmpty()) {
    @@ -223,6 +222,44 @@ public void handleMessage(Message message) {
             }
         }
         
    +    private void validatePart(MessagePartInfo p, QName elName, ServiceInfo si) {
    +        if (p == null) {
    +            throw new Fault(new org.apache.cxf.common.i18n.Message("NO_PART_FOUND", LOG, elName),
    +                            Fault.FAULT_CODE_CLIENT);
    +
    +        }
    +
    +        Boolean synth = Boolean.FALSE;
    +        if (p.getMessageInfo() != null && p.getMessageInfo().getOperation() != null) {
    +            OperationInfo op = p.getMessageInfo().getOperation();
    +            Boolean b = (Boolean)op.getProperty("operation.is.synthetic");
    +            if (b != null) {
    +                synth = b;
    +            }
    +        }
    +        if (si != null && Boolean.TRUE.equals(si.getProperty("soap.force.doclit.bare"))) {
    +            // something like a Provider service or similar that is forcing a
    +            // doc/lit/bare on an endpoint that may not really be doc/lit/bare.  
    +            // we need to just let these through per spec so the endpoint
    +            // can process it
    +            synth = true;
    +        }
    +        if (p.isElement()) {
    +            if (p.getConcreteName() != null
    +                && !elName.equals(p.getConcreteName())
    +                && !Boolean.TRUE.equals(synth)) {
    +                throw new Fault("UNEXPECTED_ELEMENT", LOG, null, elName,
    +                                p.getConcreteName());
    +            }
    +        } else {
    +            if (!(elName.equals(p.getName()) || elName.equals(p.getConcreteName()))
    +                && !Boolean.TRUE.equals(synth)) {
    +                throw new Fault("UNEXPECTED_ELEMENT", LOG, null, elName,
    +                                p.getConcreteName());
    +            }
    +        }
    +    }
    +    
         private void getPara(DepthXMLStreamReader xmlReader,
                              DataReader<XMLStreamReader> dr,
                              MessageContentsList parameters,
    
  • api/src/main/java/org/apache/cxf/interceptor/Messages.properties+1 0 modified
    @@ -40,4 +40,5 @@ COULD_NOT_FIND_SEICLASS=Could not find the class: {0}
     EXCEPTION_WHILE_WRITING_FAULT = Exception occurred while writing fault.
     EXCEPTION_WHILE_CREATING_EXCEPTION = Exception occurred while creating exception: {0}
     UNEXPECTED_WRAPPER_ELEMENT = Unexpected wrapper element {0} found.   Expected {1}.
    +UNEXPECTED_ELEMENT = Unexpected element {0} found.   Expected {1}.
      
    
  • rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/Messages.properties+1 0 modified
    @@ -31,3 +31,4 @@ INVALID_11_VERSION=A SOAP 1.2 message is not valid when sent to a SOAP 1.1 only
     NO_NAMESPACE=No namespace on "{0}" element.
     BP_2211_RPCLIT_CANNOT_BE_NULL=Cannot write part {0}. RPC/Literal parts cannot be null. (WS-I BP R2211)
     UNKNOWN_RPC_LIT_PART=Found element {0} but could not find matching RPC/Literal part
    +SOAP_ACTION_MISMATCH=The given SOAPAction {0} does not match an operation.
    
  • rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/SoapActionInInterceptor.java+51 13 modified
    @@ -22,12 +22,14 @@
     import java.util.Collection;
     import java.util.List;
     import java.util.Map;
    +import java.util.logging.Logger;
     
     import org.apache.cxf.binding.soap.Soap11;
     import org.apache.cxf.binding.soap.Soap12;
     import org.apache.cxf.binding.soap.SoapBindingConstants;
     import org.apache.cxf.binding.soap.SoapMessage;
     import org.apache.cxf.binding.soap.model.SoapOperationInfo;
    +import org.apache.cxf.common.logging.LogUtils;
     import org.apache.cxf.common.util.StringUtils;
     import org.apache.cxf.endpoint.Endpoint;
     import org.apache.cxf.helpers.CastUtils;
    @@ -40,6 +42,8 @@
     
     public class SoapActionInInterceptor extends AbstractSoapInterceptor {
         
    +    private static final Logger LOG = LogUtils.getL7dLogger(SoapActionInInterceptor.class);
    +    
         public SoapActionInInterceptor() {
             super(Phase.READ);
             addAfter(ReadHeadersInterceptor.class.getName());
    @@ -91,6 +95,10 @@ public static String getSoapAction(Message m) {
         }
         
         public void handleMessage(SoapMessage message) throws Fault {
    +        if (isRequestor(message)) {
    +            return;
    +        }
    +        
             String action = getSoapAction(message);
             if (!StringUtils.isEmpty(action)) {
                 getAndSetOperation(message, action);
    @@ -108,24 +116,54 @@ private void getAndSetOperation(SoapMessage message, String action) {
             
             BindingOperationInfo bindingOp = null;
             
    -        Collection<BindingOperationInfo> bops = ep.getBinding().getBindingInfo().getOperations();
    -        if (bops == null) {
    +        Collection<BindingOperationInfo> bops = ep.getEndpointInfo()
    +            .getBinding().getOperations();
    +        if (bops != null) {
    +            for (BindingOperationInfo boi : bops) {
    +                SoapOperationInfo soi = boi.getExtensor(SoapOperationInfo.class);
    +                if (soi != null && action.equals(soi.getAction())) {
    +                    if (bindingOp != null) {
    +                        //more than one op with the same action, will need to parse normally
    +                        return;
    +                    }
    +                    bindingOp = boi;
    +                }
    +            }
    +        }
    +        
    +        if (bindingOp == null) {
    +            //we didn't match the an operation, we'll try again later to make
    +            //sure the incoming message did end up matching an operation.
    +            //This could occur in some cases like WS-RM and WS-SecConv that will
    +            //intercept the message with a new endpoint/operation
    +            message.getInterceptorChain().add(new SoapActionInAttemptTwoInterceptor());
                 return;
             }
    -        for (BindingOperationInfo boi : bops) {
    +        
    +        ex.put(BindingOperationInfo.class, bindingOp);
    +        ex.put(OperationInfo.class, bindingOp.getOperationInfo());
    +    }
    +    
    +    public static class SoapActionInAttemptTwoInterceptor extends AbstractSoapInterceptor {
    +        public SoapActionInAttemptTwoInterceptor() {
    +            super(Phase.PRE_LOGICAL);
    +        }
    +        public void handleMessage(SoapMessage message) throws Fault {
    +            BindingOperationInfo boi = message.getExchange().getBindingOperationInfo();
    +            if (boi == null) {
    +                return;
    +            }
    +            String action = getSoapAction(message);
    +            if (StringUtils.isEmpty(action)) {
    +                return;
    +            }
                 SoapOperationInfo soi = boi.getExtensor(SoapOperationInfo.class);
    -            if (soi != null && action.equals(soi.getAction())) {
    -                if (bindingOp != null) {
    -                    //more than one op with the same action, will need to parse normally
    -                    return;
    -                }
    -                bindingOp = boi;
    +            if (soi == null || action.equals(soi.getAction())) {
    +                return;
                 }
    -        }
    -        if (bindingOp != null) {
    -            ex.put(BindingOperationInfo.class, bindingOp);
    -            ex.put(OperationInfo.class, bindingOp.getOperationInfo());
    +            throw new Fault("SOAP_ACTION_MISMATCH", LOG, null, action);
             }
         }
     
    +
     }
    
  • systests/uncategorized/src/test/java/org/apache/cxf/systest/soap/RPCEncodedSoapActionGreeterImpl.java+40 0 added
    @@ -0,0 +1,40 @@
    +/**
    + * 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.cxf.systest.soap;
    +
    +import javax.jws.WebService;
    +import javax.jws.soap.SOAPBinding;
    +
    +import org.apache.hello_world_soap_action.WrappedGreeter;
    +
    +@WebService(endpointInterface = "org.apache.hello_world_soap_action.WrappedGreeter", 
    +serviceName = "WrappedSOAPService")
    +@SOAPBinding(style = SOAPBinding.Style.RPC, use = SOAPBinding.Use.ENCODED)
    +public class RPCEncodedSoapActionGreeterImpl implements WrappedGreeter {
    +
    +    public String sayHiRequestWrapped(String in) {
    +        return "sayHi";
    +    }
    +
    +    public String sayHiRequest2Wrapped(String in) {
    +        return "sayHi2";
    +    }
    +
    +}
    
  • systests/uncategorized/src/test/java/org/apache/cxf/systest/soap/RPCLitSoapActionGreeterImpl.java+40 0 added
    @@ -0,0 +1,40 @@
    +/**
    + * 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.cxf.systest.soap;
    +
    +import javax.jws.WebService;
    +import javax.jws.soap.SOAPBinding;
    +
    +import org.apache.hello_world_soap_action.WrappedGreeter;
    +
    +@WebService(endpointInterface = "org.apache.hello_world_soap_action.WrappedGreeter", 
    +serviceName = "WrappedSOAPService")
    +@SOAPBinding(style = SOAPBinding.Style.RPC)
    +public class RPCLitSoapActionGreeterImpl implements WrappedGreeter {
    +
    +    public String sayHiRequestWrapped(String in) {
    +        return "sayHi";
    +    }
    +
    +    public String sayHiRequest2Wrapped(String in) {
    +        return "sayHi2";
    +    }
    +
    +}
    
  • systests/uncategorized/src/test/java/org/apache/cxf/systest/soap/SoapActionTest.java+390 1 modified
    @@ -19,6 +19,8 @@
     
     package org.apache.cxf.systest.soap;
     
    +import javax.xml.ws.BindingProvider;
    +
     import org.apache.cxf.Bus;
     import org.apache.cxf.BusFactory;
     import org.apache.cxf.binding.soap.Soap12;
    @@ -27,6 +29,7 @@
     import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
     import org.apache.cxf.testutil.common.TestUtil;
     import org.apache.hello_world_soap_action.Greeter;
    +import org.apache.hello_world_soap_action.WrappedGreeter;
     import org.junit.AfterClass;
     import org.junit.Assert;
     import org.junit.BeforeClass;
    @@ -35,11 +38,20 @@
     public class SoapActionTest extends Assert {
         static final String PORT1 = TestUtil.getPortNumber(SoapActionTest.class, 1);
         static final String PORT2 = TestUtil.getPortNumber(SoapActionTest.class, 2);
    +    static final String PORT3 = TestUtil.getPortNumber(SoapActionTest.class, 3);
    +    static final String PORT4 = TestUtil.getPortNumber(SoapActionTest.class, 4);
    +    static final String PORT5 = TestUtil.getPortNumber(SoapActionTest.class, 5);
    +    static final String PORT6 = TestUtil.getPortNumber(SoapActionTest.class, 6);
    +    static final String PORT7 = TestUtil.getPortNumber(SoapActionTest.class, 7);
         
         static Bus bus;
         static String add11 = "http://localhost:" + PORT1 + "/test11";
         static String add12 = "http://localhost:" + PORT2 + "/test12";
    -
    +    static String add13 = "http://localhost:" + PORT3 + "/testWrapped";
    +    static String add14 = "http://localhost:" + PORT4 + "/testWrapped12";
    +    static String add15 = "http://localhost:" + PORT5 + "/testRPCLit";
    +    static String add16 = "http://localhost:" + PORT6 + "/testRPCEncoded";
    +    static String add17 = "http://localhost:" + PORT7 + "/testWrappedEncoded";
     
         @BeforeClass
         public static void createServers() throws Exception {
    @@ -58,7 +70,40 @@ public static void createServers() throws Exception {
             config.setVersion(Soap12.getInstance());
             sf.setBindingConfig(config);
             sf.create();
    +        
    +        sf = new JaxWsServerFactoryBean();
    +        sf.setServiceBean(new WrappedSoapActionGreeterImpl());
    +        sf.setAddress(add13);
    +        sf.setBus(bus);
    +        sf.create();
    +        
    +        sf = new JaxWsServerFactoryBean();
    +        sf.setServiceBean(new WrappedSoapActionGreeterImpl());
    +        sf.setAddress(add14);
    +        sf.setBus(bus);
    +        config.setVersion(Soap12.getInstance());
    +        sf.setBindingConfig(config);
    +        sf.create();
    +        
    +        sf = new JaxWsServerFactoryBean();
    +        sf.setServiceBean(new RPCLitSoapActionGreeterImpl());
    +        sf.setAddress(add15);
    +        sf.setBus(bus);
    +        sf.create();
    +        
    +        sf = new JaxWsServerFactoryBean();
    +        sf.setServiceBean(new RPCEncodedSoapActionGreeterImpl());
    +        sf.setAddress(add16);
    +        sf.setBus(bus);
    +        sf.create();
    +        
    +        sf = new JaxWsServerFactoryBean();
    +        sf.setServiceBean(new WrappedEncodedSoapActionGreeterImpl());
    +        sf.setAddress(add17);
    +        sf.setBus(bus);
    +        sf.create();
         }
    +    
         @AfterClass
         public static void shutdown() throws Exception {
             bus.shutdown(true);
    @@ -93,4 +138,348 @@ public void testSoap12Endpoint() throws Exception {
             assertEquals("sayHi", greeter.sayHi("test"));
             assertEquals("sayHi2", greeter.sayHi2("test"));
         }
    +    
    +    
    +    @Test
    +    public void testBareSoapActionSpoofing() throws Exception {
    +        JaxWsProxyFactoryBean pf = new JaxWsProxyFactoryBean();
    +        pf.setServiceClass(Greeter.class);
    +        pf.setAddress(add11);
    +        pf.setBus(bus);
    +        Greeter greeter = (Greeter) pf.create();
    +        
    +        assertEquals("sayHi", greeter.sayHi("test"));
    +        assertEquals("sayHi2", greeter.sayHi2("test"));        
    +        
    +        // Now test spoofing attack
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_2"
    +        );
    +        try {
    +            greeter.sayHi("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test the other operation
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_1"
    +        );
    +        try {
    +            greeter.sayHi2("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test a SOAP Action that does not exist in the binding
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_UNKNOWN"
    +        );
    +        try {
    +            greeter.sayHi("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +    }
    +    
    +    @Test
    +    public void testBareSoap12ActionSpoofing() throws Exception {
    +        JaxWsProxyFactoryBean pf = new JaxWsProxyFactoryBean();
    +        pf.setServiceClass(Greeter.class);
    +        pf.setAddress(add12);
    +        SoapBindingConfiguration config = new SoapBindingConfiguration();
    +        config.setVersion(Soap12.getInstance());
    +        pf.setBindingConfig(config);
    +        pf.setBus(bus);
    +        Greeter greeter = (Greeter) pf.create();
    +        
    +        assertEquals("sayHi", greeter.sayHi("test"));
    +        assertEquals("sayHi2", greeter.sayHi2("test"));        
    +        
    +        // Now test spoofing attack
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_2"
    +        );
    +        try {
    +            greeter.sayHi("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test the other operation
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_1"
    +        );
    +        try {
    +            greeter.sayHi2("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test a SOAP Action that does not exist in the binding
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_UNKNOWN"
    +        );
    +        try {
    +            greeter.sayHi("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +    }
    +    
    +    @Test
    +    public void testWrappedSoapActionSpoofing() throws Exception {
    +        JaxWsProxyFactoryBean pf = new JaxWsProxyFactoryBean();
    +        pf.setServiceClass(WrappedGreeter.class);
    +        pf.setAddress(add13);
    +        pf.setBus(bus);
    +        WrappedGreeter greeter = (WrappedGreeter) pf.create();
    +        
    +        assertEquals("sayHi", greeter.sayHiRequestWrapped("test"));
    +        assertEquals("sayHi2", greeter.sayHiRequest2Wrapped("test"));        
    +        
    +        // Now test spoofing attack
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_2"
    +        );
    +        try {
    +            greeter.sayHiRequestWrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test the other operation
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_1"
    +        );
    +        try {
    +            greeter.sayHiRequest2Wrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test a SOAP Action that does not exist in the binding
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_UNKNOWN"
    +        );
    +        try {
    +            greeter.sayHiRequestWrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +    }
    +    
    +    @Test
    +    public void testWrappedSoap12ActionSpoofing() throws Exception {
    +        JaxWsProxyFactoryBean pf = new JaxWsProxyFactoryBean();
    +        pf.setServiceClass(WrappedGreeter.class);
    +        pf.setAddress(add14);
    +        SoapBindingConfiguration config = new SoapBindingConfiguration();
    +        config.setVersion(Soap12.getInstance());
    +        pf.setBindingConfig(config);
    +        pf.setBus(bus);
    +        WrappedGreeter greeter = (WrappedGreeter) pf.create();
    +        
    +        assertEquals("sayHi", greeter.sayHiRequestWrapped("test"));
    +        assertEquals("sayHi2", greeter.sayHiRequest2Wrapped("test"));        
    +        
    +        // Now test spoofing attack
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_2"
    +        );
    +        try {
    +            greeter.sayHiRequestWrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test the other operation
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_1"
    +        );
    +        try {
    +            greeter.sayHiRequest2Wrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test a SOAP Action that does not exist in the binding
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_UNKNOWN"
    +        );
    +        try {
    +            greeter.sayHiRequestWrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +    }
    +    
    +    @Test
    +    public void testRPCLitSoapActionSpoofing() throws Exception {
    +        JaxWsProxyFactoryBean pf = new JaxWsProxyFactoryBean();
    +        pf.setServiceClass(WrappedGreeter.class);
    +        pf.setAddress(add15);
    +        pf.setBus(bus);
    +        WrappedGreeter greeter = (WrappedGreeter) pf.create();
    +        
    +        assertEquals("sayHi", greeter.sayHiRequestWrapped("test"));
    +        assertEquals("sayHi2", greeter.sayHiRequest2Wrapped("test"));        
    +        
    +        // Now test spoofing attack
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_2"
    +        );
    +        try {
    +            greeter.sayHiRequestWrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test the other operation
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_1"
    +        );
    +        try {
    +            greeter.sayHiRequest2Wrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test a SOAP Action that does not exist in the binding
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_UNKNOWN"
    +        );
    +        try {
    +            greeter.sayHiRequestWrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +    }
    +    
    +    @Test
    +    public void testRPCEncodedSoapActionSpoofing() throws Exception {
    +        JaxWsProxyFactoryBean pf = new JaxWsProxyFactoryBean();
    +        pf.setServiceClass(WrappedGreeter.class);
    +        pf.setAddress(add16);
    +        pf.setBus(bus);
    +        WrappedGreeter greeter = (WrappedGreeter) pf.create();
    +        
    +        assertEquals("sayHi", greeter.sayHiRequestWrapped("test"));
    +        assertEquals("sayHi2", greeter.sayHiRequest2Wrapped("test"));        
    +        
    +        // Now test spoofing attack
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_2"
    +        );
    +        try {
    +            greeter.sayHiRequestWrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test the other operation
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_1"
    +        );
    +        try {
    +            greeter.sayHiRequest2Wrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test a SOAP Action that does not exist in the binding
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_UNKNOWN"
    +        );
    +        try {
    +            greeter.sayHiRequestWrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +    }
    +    
    +    @Test
    +    public void testWrappedEncodedSoapActionSpoofing() throws Exception {
    +        JaxWsProxyFactoryBean pf = new JaxWsProxyFactoryBean();
    +        pf.setServiceClass(WrappedGreeter.class);
    +        pf.setAddress(add17);
    +        pf.setBus(bus);
    +        WrappedGreeter greeter = (WrappedGreeter) pf.create();
    +        
    +        assertEquals("sayHi", greeter.sayHiRequestWrapped("test"));
    +        assertEquals("sayHi2", greeter.sayHiRequest2Wrapped("test"));        
    +        
    +        // Now test spoofing attack
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_2"
    +        );
    +        try {
    +            greeter.sayHiRequestWrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test the other operation
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_1"
    +        );
    +        try {
    +            greeter.sayHiRequest2Wrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test a SOAP Action that does not exist in the binding
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_UNKNOWN"
    +        );
    +        try {
    +            greeter.sayHiRequestWrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +    }
    +    
     }
    
  • systests/uncategorized/src/test/java/org/apache/cxf/systest/soap/WrappedEncodedSoapActionGreeterImpl.java+40 0 added
    @@ -0,0 +1,40 @@
    +/**
    + * 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.cxf.systest.soap;
    +
    +import javax.jws.WebService;
    +import javax.jws.soap.SOAPBinding;
    +
    +import org.apache.hello_world_soap_action.WrappedGreeter;
    +
    +@WebService(endpointInterface = "org.apache.hello_world_soap_action.WrappedGreeter", 
    +            serviceName = "WrappedSOAPService")
    +@SOAPBinding(use = SOAPBinding.Use.ENCODED)
    +public class WrappedEncodedSoapActionGreeterImpl implements WrappedGreeter {
    +
    +    public String sayHiRequestWrapped(String in) {
    +        return "sayHi";
    +    }
    +
    +    public String sayHiRequest2Wrapped(String in) {
    +        return "sayHi2";
    +    }
    +
    +}
    
  • systests/uncategorized/src/test/java/org/apache/cxf/systest/soap/WrappedSoapActionGreeterImpl.java+38 0 added
    @@ -0,0 +1,38 @@
    +/**
    + * 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.cxf.systest.soap;
    +
    +import javax.jws.WebService;
    +
    +import org.apache.hello_world_soap_action.WrappedGreeter;
    +
    +@WebService(endpointInterface = "org.apache.hello_world_soap_action.WrappedGreeter", 
    +            serviceName = "WrappedSOAPService")
    +public class WrappedSoapActionGreeterImpl implements WrappedGreeter {
    +
    +    public String sayHiRequestWrapped(String in) {
    +        return "sayHi";
    +    }
    +
    +    public String sayHiRequest2Wrapped(String in) {
    +        return "sayHi2";
    +    }
    +
    +}
    
  • testutils/src/main/resources/wsdl/hello_world_soap_action.wsdl+115 0 modified
    @@ -26,6 +26,7 @@
       xmlns:jms="http://cxf.apache.org/transports/jms"
       xmlns:tns="http://apache.org/hello_world_soap_action"
       xmlns:x1="http://apache.org/hello_world_soap_action/types"
    +  xmlns:x2="http://apache.org/hello_world_soap_action/types/wrapped"
       xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
       targetNamespace="http://apache.org/hello_world_soap_action"
       name="HelloWorld">
    @@ -37,6 +38,36 @@
           <element name="text" type="xsd:string" />
           <element name="text2" type="xsd:string" />
         </schema>
    +    <xsd:schema targetNamespace="http://apache.org/hello_world_soap_action/types/wrapped">
    +            <xsd:element name="sayHiRequestWrapped">
    +                <xsd:complexType>
    +                    <xsd:sequence>
    +                        <xsd:element name="wrappedText" type="xsd:string" />
    +                    </xsd:sequence>
    +                </xsd:complexType>
    +            </xsd:element>
    +            <xsd:element name="sayHiResponseWrapped">
    +                <xsd:complexType>
    +                    <xsd:sequence>
    +                        <xsd:element name="wrappedTextResponse" type="xsd:string" />
    +                    </xsd:sequence>
    +                </xsd:complexType>
    +            </xsd:element>
    +            <xsd:element name="sayHiRequest2Wrapped">
    +                <xsd:complexType>
    +                    <xsd:sequence>
    +                        <xsd:element name="wrappedText" type="xsd:string" />
    +                    </xsd:sequence>
    +                </xsd:complexType>
    +            </xsd:element>
    +            <xsd:element name="sayHiResponse2Wrapped">
    +                <xsd:complexType>
    +                    <xsd:sequence>
    +                        <xsd:element name="wrappedTextResponse" type="xsd:string" />
    +                    </xsd:sequence>
    +                </xsd:complexType>
    +            </xsd:element>
    +        </xsd:schema>
       </wsdl:types>
       <wsdl:message name="sayHiRequest">
         <wsdl:part name="in" element="x1:text" />
    @@ -50,6 +81,19 @@
       <wsdl:message name="sayHiResponse2">
         <wsdl:part name="out" element="x1:text" />
       </wsdl:message>
    +  
    +  <wsdl:message name="sayHiRequestWrapped">
    +        <wsdl:part element="x2:sayHiRequestWrapped" name="parameters" />
    +  </wsdl:message>
    +  <wsdl:message name="sayHiResponseWrapped">
    +        <wsdl:part element="x2:sayHiResponseWrapped" name="parameters" />
    +  </wsdl:message>
    +  <wsdl:message name="sayHiRequest2Wrapped">
    +        <wsdl:part element="x2:sayHiRequest2Wrapped" name="parameters" />
    +  </wsdl:message>
    +  <wsdl:message name="sayHiResponse2Wrapped">
    +        <wsdl:part element="x2:sayHiResponse2Wrapped" name="parameters" />
    +  </wsdl:message>
     
       <wsdl:portType name="Greeter">
         <wsdl:operation name="sayHi">
    @@ -63,6 +107,19 @@
         </wsdl:operation>
     
       </wsdl:portType>
    +  
    +  <wsdl:portType name="WrappedGreeter">
    +        <wsdl:operation name="sayHiRequestWrapped">
    +            <wsdl:input message="tns:sayHiRequestWrapped" />
    +            <wsdl:output message="tns:sayHiResponseWrapped" />
    +        </wsdl:operation>
    +        
    +        <wsdl:operation name="sayHiRequest2Wrapped">
    +            <wsdl:input message="tns:sayHiRequest2Wrapped" />
    +            <wsdl:output message="tns:sayHiResponse2Wrapped" />
    +        </wsdl:operation>
    +  </wsdl:portType>
    +  
       <wsdl:binding name="Greeter_SOAPBinding" type="tns:Greeter">
         <soap:binding style="document"
           transport="http://schemas.xmlsoap.org/soap/http" />
    @@ -86,6 +143,7 @@
         </wsdl:operation>
     
       </wsdl:binding>
    +  
       <wsdl:binding name="Greeter_SOAP12Binding" type="tns:Greeter">
         <soap12:binding style="document"
           transport="http://www.w3.org/2003/05/soap/bindings/HTTP/" />
    @@ -109,6 +167,53 @@
         </wsdl:operation>
         
       </wsdl:binding>
    +  
    +  <wsdl:binding name="Greeter_WrappedSOAPBinding" type="tns:WrappedGreeter">
    +        <soap:binding style="document"
    +            transport="http://schemas.xmlsoap.org/soap/http" />
    +        <wsdl:operation name="sayHiRequestWrapped">
    +            <soap:operation soapAction="SAY_HI_1" />
    +            <wsdl:input>
    +                <soap:body use="literal" />
    +            </wsdl:input>
    +            <wsdl:output>
    +                <soap:body use="literal" />
    +            </wsdl:output>
    +        </wsdl:operation>
    +        <wsdl:operation name="sayHiRequest2Wrapped">
    +            <soap:operation soapAction="SAY_HI_2" />
    +            <wsdl:input>
    +                <soap:body use="literal" />
    +            </wsdl:input>
    +            <wsdl:output>
    +                <soap:body use="literal" />
    +            </wsdl:output>
    +        </wsdl:operation>
    +  </wsdl:binding>     
    +  
    +  <wsdl:binding name="Greeter_WrappedSOAP12Binding" type="tns:WrappedGreeter">
    +        <soap12:binding style="document"
    +            transport="http://www.w3.org/2003/05/soap/bindings/HTTP/" />
    +        <wsdl:operation name="sayHiRequestWrapped">
    +            <soap12:operation soapAction="SAY_HI_1" />
    +            <wsdl:input>
    +                <soap12:body use="literal" />
    +            </wsdl:input>
    +            <wsdl:output>
    +                <soap12:body use="literal" />
    +            </wsdl:output>
    +        </wsdl:operation>
    +        <wsdl:operation name="sayHiRequest2Wrapped">
    +            <soap12:operation soapAction="SAY_HI_2" />
    +            <wsdl:input>
    +                <soap12:body use="literal" />
    +            </wsdl:input>
    +            <wsdl:output>
    +                <soap12:body use="literal" />
    +            </wsdl:output>
    +        </wsdl:operation>
    +  </wsdl:binding>     
    +  
       <wsdl:service name="SOAPService">
         <wsdl:port name="SoapPort" binding="tns:Greeter_SOAPBinding">
           <soap:address
    @@ -121,4 +226,14 @@
             location="http://localhost:9001/SOAPDocLitService/Soap12Port" />
         </wsdl:port>
       </wsdl:service>
    +  <wsdl:service name="WrappedSOAPService">
    +      <wsdl:port name="WrappedSoapPort" binding="tns:Greeter_WrappedSOAPBinding">
    +            <soap:address location="http://localhost:9001/SOAPDocLitService/WrappedSoapPort" />
    +      </wsdl:port>
    +  </wsdl:service>
    +  <wsdl:service name="WrappedSOAP12Service">
    +      <wsdl:port name="WrappedSoap12Port" binding="tns:Greeter_WrappedSOAP12Binding">
    +            <soap:address location="http://localhost:9001/SOAPDocLitService/WrappedSoap12Port" />
    +      </wsdl:port>
    +  </wsdl:service>
     </wsdl:definitions>
    
9c70abe28fbf

Some improvements to handling SOAP Actions

https://github.com/apache/cxfColm O HeigeartaighAug 2, 2012via ghsa
10 files changed · +759 20
  • api/src/main/java/org/apache/cxf/interceptor/DocLiteralInInterceptor.java+43 6 modified
    @@ -191,12 +191,11 @@ public void handleMessage(Message message) {
                         } else {
                             p = findMessagePart(exchange, operations, elName, client, paramNum, message);
                         }
    -    
    -                    if (p == null) {
    -                        throw new Fault(new org.apache.cxf.common.i18n.Message("NO_PART_FOUND", LOG, elName),
    -                                        Fault.FAULT_CODE_CLIENT);
    -                    }
    -    
    +                    
    +                    //Make sure the elName found on the wire is actually OK for 
    +                    //the purpose we need it
    +                    validatePart(p, elName, si);
    +
                         o = dr.read(p, xmlReader);
                         if (Boolean.TRUE.equals(si.getProperty("soap.force.doclit.bare")) 
                             && parameters.isEmpty()) {
    @@ -223,6 +222,44 @@ public void handleMessage(Message message) {
             }
         }
         
    +    private void validatePart(MessagePartInfo p, QName elName, ServiceInfo si) {
    +        if (p == null) {
    +            throw new Fault(new org.apache.cxf.common.i18n.Message("NO_PART_FOUND", LOG, elName),
    +                            Fault.FAULT_CODE_CLIENT);
    +
    +        }
    +
    +        Boolean synth = Boolean.FALSE;
    +        if (p.getMessageInfo() != null && p.getMessageInfo().getOperation() != null) {
    +            OperationInfo op = p.getMessageInfo().getOperation();
    +            Boolean b = (Boolean)op.getProperty("operation.is.synthetic");
    +            if (b != null) {
    +                synth = b;
    +            }
    +        }
    +        if (si != null && Boolean.TRUE.equals(si.getProperty("soap.force.doclit.bare"))) {
    +            // something like a Provider service or similar that is forcing a
    +            // doc/lit/bare on an endpoint that may not really be doc/lit/bare.  
    +            // we need to just let these through per spec so the endpoint
    +            // can process it
    +            synth = true;
    +        }
    +        if (p.isElement()) {
    +            if (p.getConcreteName() != null
    +                && !elName.equals(p.getConcreteName())
    +                && !Boolean.TRUE.equals(synth)) {
    +                throw new Fault("UNEXPECTED_ELEMENT", LOG, null, elName,
    +                                p.getConcreteName());
    +            }
    +        } else {
    +            if (!(elName.equals(p.getName()) || elName.equals(p.getConcreteName()))
    +                && !Boolean.TRUE.equals(synth)) {
    +                throw new Fault("UNEXPECTED_ELEMENT", LOG, null, elName,
    +                                p.getConcreteName());
    +            }
    +        }
    +    }
    +    
         private void getPara(DepthXMLStreamReader xmlReader,
                              DataReader<XMLStreamReader> dr,
                              MessageContentsList parameters,
    
  • api/src/main/java/org/apache/cxf/interceptor/Messages.properties+1 0 modified
    @@ -40,4 +40,5 @@ COULD_NOT_FIND_SEICLASS=Could not find the class: {0}
     EXCEPTION_WHILE_WRITING_FAULT = Exception occurred while writing fault.
     EXCEPTION_WHILE_CREATING_EXCEPTION = Exception occurred while creating exception: {0}
     UNEXPECTED_WRAPPER_ELEMENT = Unexpected wrapper element {0} found.   Expected {1}.
    +UNEXPECTED_ELEMENT = Unexpected element {0} found.   Expected {1}.
      
    
  • rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/Messages.properties+1 0 modified
    @@ -31,3 +31,4 @@ INVALID_11_VERSION=A SOAP 1.2 message is not valid when sent to a SOAP 1.1 only
     NO_NAMESPACE=No namespace on "{0}" element.
     BP_2211_RPCLIT_CANNOT_BE_NULL=Cannot write part {0}. RPC/Literal parts cannot be null. (WS-I BP R2211)
     UNKNOWN_RPC_LIT_PART=Found element {0} but could not find matching RPC/Literal part
    +SOAP_ACTION_MISMATCH=The given SOAPAction {0} does not match an operation.
    
  • rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/SoapActionInInterceptor.java+51 13 modified
    @@ -22,12 +22,14 @@
     import java.util.Collection;
     import java.util.List;
     import java.util.Map;
    +import java.util.logging.Logger;
     
     import org.apache.cxf.binding.soap.Soap11;
     import org.apache.cxf.binding.soap.Soap12;
     import org.apache.cxf.binding.soap.SoapBindingConstants;
     import org.apache.cxf.binding.soap.SoapMessage;
     import org.apache.cxf.binding.soap.model.SoapOperationInfo;
    +import org.apache.cxf.common.logging.LogUtils;
     import org.apache.cxf.common.util.StringUtils;
     import org.apache.cxf.endpoint.Endpoint;
     import org.apache.cxf.helpers.CastUtils;
    @@ -40,6 +42,8 @@
     
     public class SoapActionInInterceptor extends AbstractSoapInterceptor {
         
    +    private static final Logger LOG = LogUtils.getL7dLogger(SoapActionInInterceptor.class);
    +    
         public SoapActionInInterceptor() {
             super(Phase.READ);
             addAfter(ReadHeadersInterceptor.class.getName());
    @@ -91,6 +95,10 @@ public static String getSoapAction(Message m) {
         }
         
         public void handleMessage(SoapMessage message) throws Fault {
    +        if (isRequestor(message)) {
    +            return;
    +        }
    +        
             String action = getSoapAction(message);
             if (!StringUtils.isEmpty(action)) {
                 getAndSetOperation(message, action);
    @@ -108,24 +116,54 @@ private void getAndSetOperation(SoapMessage message, String action) {
             
             BindingOperationInfo bindingOp = null;
             
    -        Collection<BindingOperationInfo> bops = ep.getBinding().getBindingInfo().getOperations();
    -        if (bops == null) {
    +        Collection<BindingOperationInfo> bops = ep.getEndpointInfo()
    +            .getBinding().getOperations();
    +        if (bops != null) {
    +            for (BindingOperationInfo boi : bops) {
    +                SoapOperationInfo soi = boi.getExtensor(SoapOperationInfo.class);
    +                if (soi != null && action.equals(soi.getAction())) {
    +                    if (bindingOp != null) {
    +                        //more than one op with the same action, will need to parse normally
    +                        return;
    +                    }
    +                    bindingOp = boi;
    +                }
    +            }
    +        }
    +        
    +        if (bindingOp == null) {
    +            //we didn't match the an operation, we'll try again later to make
    +            //sure the incoming message did end up matching an operation.
    +            //This could occur in some cases like WS-RM and WS-SecConv that will
    +            //intercept the message with a new endpoint/operation
    +            message.getInterceptorChain().add(new SoapActionInAttemptTwoInterceptor());
                 return;
             }
    -        for (BindingOperationInfo boi : bops) {
    +        
    +        ex.put(BindingOperationInfo.class, bindingOp);
    +        ex.put(OperationInfo.class, bindingOp.getOperationInfo());
    +    }
    +    
    +    public static class SoapActionInAttemptTwoInterceptor extends AbstractSoapInterceptor {
    +        public SoapActionInAttemptTwoInterceptor() {
    +            super(Phase.PRE_LOGICAL);
    +        }
    +        public void handleMessage(SoapMessage message) throws Fault {
    +            BindingOperationInfo boi = message.getExchange().getBindingOperationInfo();
    +            if (boi == null) {
    +                return;
    +            }
    +            String action = getSoapAction(message);
    +            if (StringUtils.isEmpty(action)) {
    +                return;
    +            }
                 SoapOperationInfo soi = boi.getExtensor(SoapOperationInfo.class);
    -            if (soi != null && action.equals(soi.getAction())) {
    -                if (bindingOp != null) {
    -                    //more than one op with the same action, will need to parse normally
    -                    return;
    -                }
    -                bindingOp = boi;
    +            if (soi == null || action.equals(soi.getAction())) {
    +                return;
                 }
    -        }
    -        if (bindingOp != null) {
    -            ex.put(BindingOperationInfo.class, bindingOp);
    -            ex.put(OperationInfo.class, bindingOp.getOperationInfo());
    +            throw new Fault("SOAP_ACTION_MISMATCH", LOG, null, action);
             }
         }
     
    +
     }
    
  • systests/uncategorized/src/test/java/org/apache/cxf/systest/soap/RPCEncodedSoapActionGreeterImpl.java+40 0 added
    @@ -0,0 +1,40 @@
    +/**
    + * 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.cxf.systest.soap;
    +
    +import javax.jws.WebService;
    +import javax.jws.soap.SOAPBinding;
    +
    +import org.apache.hello_world_soap_action.WrappedGreeter;
    +
    +@WebService(endpointInterface = "org.apache.hello_world_soap_action.WrappedGreeter", 
    +serviceName = "WrappedSOAPService")
    +@SOAPBinding(style = SOAPBinding.Style.RPC, use = SOAPBinding.Use.ENCODED)
    +public class RPCEncodedSoapActionGreeterImpl implements WrappedGreeter {
    +
    +    public String sayHiRequestWrapped(String in) {
    +        return "sayHi";
    +    }
    +
    +    public String sayHiRequest2Wrapped(String in) {
    +        return "sayHi2";
    +    }
    +
    +}
    
  • systests/uncategorized/src/test/java/org/apache/cxf/systest/soap/RPCLitSoapActionGreeterImpl.java+40 0 added
    @@ -0,0 +1,40 @@
    +/**
    + * 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.cxf.systest.soap;
    +
    +import javax.jws.WebService;
    +import javax.jws.soap.SOAPBinding;
    +
    +import org.apache.hello_world_soap_action.WrappedGreeter;
    +
    +@WebService(endpointInterface = "org.apache.hello_world_soap_action.WrappedGreeter", 
    +serviceName = "WrappedSOAPService")
    +@SOAPBinding(style = SOAPBinding.Style.RPC)
    +public class RPCLitSoapActionGreeterImpl implements WrappedGreeter {
    +
    +    public String sayHiRequestWrapped(String in) {
    +        return "sayHi";
    +    }
    +
    +    public String sayHiRequest2Wrapped(String in) {
    +        return "sayHi2";
    +    }
    +
    +}
    
  • systests/uncategorized/src/test/java/org/apache/cxf/systest/soap/SoapActionTest.java+390 1 modified
    @@ -19,6 +19,8 @@
     
     package org.apache.cxf.systest.soap;
     
    +import javax.xml.ws.BindingProvider;
    +
     import org.apache.cxf.Bus;
     import org.apache.cxf.BusFactory;
     import org.apache.cxf.binding.soap.Soap12;
    @@ -27,6 +29,7 @@
     import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
     import org.apache.cxf.testutil.common.TestUtil;
     import org.apache.hello_world_soap_action.Greeter;
    +import org.apache.hello_world_soap_action.WrappedGreeter;
     import org.junit.AfterClass;
     import org.junit.Assert;
     import org.junit.BeforeClass;
    @@ -35,11 +38,20 @@
     public class SoapActionTest extends Assert {
         static final String PORT1 = TestUtil.getPortNumber(SoapActionTest.class, 1);
         static final String PORT2 = TestUtil.getPortNumber(SoapActionTest.class, 2);
    +    static final String PORT3 = TestUtil.getPortNumber(SoapActionTest.class, 3);
    +    static final String PORT4 = TestUtil.getPortNumber(SoapActionTest.class, 4);
    +    static final String PORT5 = TestUtil.getPortNumber(SoapActionTest.class, 5);
    +    static final String PORT6 = TestUtil.getPortNumber(SoapActionTest.class, 6);
    +    static final String PORT7 = TestUtil.getPortNumber(SoapActionTest.class, 7);
         
         static Bus bus;
         static String add11 = "http://localhost:" + PORT1 + "/test11";
         static String add12 = "http://localhost:" + PORT2 + "/test12";
    -
    +    static String add13 = "http://localhost:" + PORT3 + "/testWrapped";
    +    static String add14 = "http://localhost:" + PORT4 + "/testWrapped12";
    +    static String add15 = "http://localhost:" + PORT5 + "/testRPCLit";
    +    static String add16 = "http://localhost:" + PORT6 + "/testRPCEncoded";
    +    static String add17 = "http://localhost:" + PORT7 + "/testWrappedEncoded";
     
         @BeforeClass
         public static void createServers() throws Exception {
    @@ -58,7 +70,40 @@ public static void createServers() throws Exception {
             config.setVersion(Soap12.getInstance());
             sf.setBindingConfig(config);
             sf.create();
    +        
    +        sf = new JaxWsServerFactoryBean();
    +        sf.setServiceBean(new WrappedSoapActionGreeterImpl());
    +        sf.setAddress(add13);
    +        sf.setBus(bus);
    +        sf.create();
    +        
    +        sf = new JaxWsServerFactoryBean();
    +        sf.setServiceBean(new WrappedSoapActionGreeterImpl());
    +        sf.setAddress(add14);
    +        sf.setBus(bus);
    +        config.setVersion(Soap12.getInstance());
    +        sf.setBindingConfig(config);
    +        sf.create();
    +        
    +        sf = new JaxWsServerFactoryBean();
    +        sf.setServiceBean(new RPCLitSoapActionGreeterImpl());
    +        sf.setAddress(add15);
    +        sf.setBus(bus);
    +        sf.create();
    +        
    +        sf = new JaxWsServerFactoryBean();
    +        sf.setServiceBean(new RPCEncodedSoapActionGreeterImpl());
    +        sf.setAddress(add16);
    +        sf.setBus(bus);
    +        sf.create();
    +        
    +        sf = new JaxWsServerFactoryBean();
    +        sf.setServiceBean(new WrappedEncodedSoapActionGreeterImpl());
    +        sf.setAddress(add17);
    +        sf.setBus(bus);
    +        sf.create();
         }
    +    
         @AfterClass
         public static void shutdown() throws Exception {
             bus.shutdown(true);
    @@ -93,4 +138,348 @@ public void testSoap12Endpoint() throws Exception {
             assertEquals("sayHi", greeter.sayHi("test"));
             assertEquals("sayHi2", greeter.sayHi2("test"));
         }
    +    
    +    
    +    @Test
    +    public void testBareSoapActionSpoofing() throws Exception {
    +        JaxWsProxyFactoryBean pf = new JaxWsProxyFactoryBean();
    +        pf.setServiceClass(Greeter.class);
    +        pf.setAddress(add11);
    +        pf.setBus(bus);
    +        Greeter greeter = (Greeter) pf.create();
    +        
    +        assertEquals("sayHi", greeter.sayHi("test"));
    +        assertEquals("sayHi2", greeter.sayHi2("test"));        
    +        
    +        // Now test spoofing attack
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_2"
    +        );
    +        try {
    +            greeter.sayHi("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test the other operation
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_1"
    +        );
    +        try {
    +            greeter.sayHi2("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test a SOAP Action that does not exist in the binding
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_UNKNOWN"
    +        );
    +        try {
    +            greeter.sayHi("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +    }
    +    
    +    @Test
    +    public void testBareSoap12ActionSpoofing() throws Exception {
    +        JaxWsProxyFactoryBean pf = new JaxWsProxyFactoryBean();
    +        pf.setServiceClass(Greeter.class);
    +        pf.setAddress(add12);
    +        SoapBindingConfiguration config = new SoapBindingConfiguration();
    +        config.setVersion(Soap12.getInstance());
    +        pf.setBindingConfig(config);
    +        pf.setBus(bus);
    +        Greeter greeter = (Greeter) pf.create();
    +        
    +        assertEquals("sayHi", greeter.sayHi("test"));
    +        assertEquals("sayHi2", greeter.sayHi2("test"));        
    +        
    +        // Now test spoofing attack
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_2"
    +        );
    +        try {
    +            greeter.sayHi("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test the other operation
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_1"
    +        );
    +        try {
    +            greeter.sayHi2("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test a SOAP Action that does not exist in the binding
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_UNKNOWN"
    +        );
    +        try {
    +            greeter.sayHi("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +    }
    +    
    +    @Test
    +    public void testWrappedSoapActionSpoofing() throws Exception {
    +        JaxWsProxyFactoryBean pf = new JaxWsProxyFactoryBean();
    +        pf.setServiceClass(WrappedGreeter.class);
    +        pf.setAddress(add13);
    +        pf.setBus(bus);
    +        WrappedGreeter greeter = (WrappedGreeter) pf.create();
    +        
    +        assertEquals("sayHi", greeter.sayHiRequestWrapped("test"));
    +        assertEquals("sayHi2", greeter.sayHiRequest2Wrapped("test"));        
    +        
    +        // Now test spoofing attack
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_2"
    +        );
    +        try {
    +            greeter.sayHiRequestWrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test the other operation
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_1"
    +        );
    +        try {
    +            greeter.sayHiRequest2Wrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test a SOAP Action that does not exist in the binding
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_UNKNOWN"
    +        );
    +        try {
    +            greeter.sayHiRequestWrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +    }
    +    
    +    @Test
    +    public void testWrappedSoap12ActionSpoofing() throws Exception {
    +        JaxWsProxyFactoryBean pf = new JaxWsProxyFactoryBean();
    +        pf.setServiceClass(WrappedGreeter.class);
    +        pf.setAddress(add14);
    +        SoapBindingConfiguration config = new SoapBindingConfiguration();
    +        config.setVersion(Soap12.getInstance());
    +        pf.setBindingConfig(config);
    +        pf.setBus(bus);
    +        WrappedGreeter greeter = (WrappedGreeter) pf.create();
    +        
    +        assertEquals("sayHi", greeter.sayHiRequestWrapped("test"));
    +        assertEquals("sayHi2", greeter.sayHiRequest2Wrapped("test"));        
    +        
    +        // Now test spoofing attack
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_2"
    +        );
    +        try {
    +            greeter.sayHiRequestWrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test the other operation
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_1"
    +        );
    +        try {
    +            greeter.sayHiRequest2Wrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test a SOAP Action that does not exist in the binding
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_UNKNOWN"
    +        );
    +        try {
    +            greeter.sayHiRequestWrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +    }
    +    
    +    @Test
    +    public void testRPCLitSoapActionSpoofing() throws Exception {
    +        JaxWsProxyFactoryBean pf = new JaxWsProxyFactoryBean();
    +        pf.setServiceClass(WrappedGreeter.class);
    +        pf.setAddress(add15);
    +        pf.setBus(bus);
    +        WrappedGreeter greeter = (WrappedGreeter) pf.create();
    +        
    +        assertEquals("sayHi", greeter.sayHiRequestWrapped("test"));
    +        assertEquals("sayHi2", greeter.sayHiRequest2Wrapped("test"));        
    +        
    +        // Now test spoofing attack
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_2"
    +        );
    +        try {
    +            greeter.sayHiRequestWrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test the other operation
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_1"
    +        );
    +        try {
    +            greeter.sayHiRequest2Wrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test a SOAP Action that does not exist in the binding
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_UNKNOWN"
    +        );
    +        try {
    +            greeter.sayHiRequestWrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +    }
    +    
    +    @Test
    +    public void testRPCEncodedSoapActionSpoofing() throws Exception {
    +        JaxWsProxyFactoryBean pf = new JaxWsProxyFactoryBean();
    +        pf.setServiceClass(WrappedGreeter.class);
    +        pf.setAddress(add16);
    +        pf.setBus(bus);
    +        WrappedGreeter greeter = (WrappedGreeter) pf.create();
    +        
    +        assertEquals("sayHi", greeter.sayHiRequestWrapped("test"));
    +        assertEquals("sayHi2", greeter.sayHiRequest2Wrapped("test"));        
    +        
    +        // Now test spoofing attack
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_2"
    +        );
    +        try {
    +            greeter.sayHiRequestWrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test the other operation
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_1"
    +        );
    +        try {
    +            greeter.sayHiRequest2Wrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test a SOAP Action that does not exist in the binding
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_UNKNOWN"
    +        );
    +        try {
    +            greeter.sayHiRequestWrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +    }
    +    
    +    @Test
    +    public void testWrappedEncodedSoapActionSpoofing() throws Exception {
    +        JaxWsProxyFactoryBean pf = new JaxWsProxyFactoryBean();
    +        pf.setServiceClass(WrappedGreeter.class);
    +        pf.setAddress(add17);
    +        pf.setBus(bus);
    +        WrappedGreeter greeter = (WrappedGreeter) pf.create();
    +        
    +        assertEquals("sayHi", greeter.sayHiRequestWrapped("test"));
    +        assertEquals("sayHi2", greeter.sayHiRequest2Wrapped("test"));        
    +        
    +        // Now test spoofing attack
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_2"
    +        );
    +        try {
    +            greeter.sayHiRequestWrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test the other operation
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_1"
    +        );
    +        try {
    +            greeter.sayHiRequest2Wrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +        
    +        // Test a SOAP Action that does not exist in the binding
    +        ((BindingProvider)greeter).getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, "true");
    +        ((BindingProvider)greeter).getRequestContext().put(
    +            BindingProvider.SOAPACTION_URI_PROPERTY, "SAY_HI_UNKNOWN"
    +        );
    +        try {
    +            greeter.sayHiRequestWrapped("test");
    +            fail("Failure expected on spoofing attack");
    +        } catch (Exception ex) {
    +            // expected
    +        }
    +    }
    +    
     }
    
  • systests/uncategorized/src/test/java/org/apache/cxf/systest/soap/WrappedEncodedSoapActionGreeterImpl.java+40 0 added
    @@ -0,0 +1,40 @@
    +/**
    + * 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.cxf.systest.soap;
    +
    +import javax.jws.WebService;
    +import javax.jws.soap.SOAPBinding;
    +
    +import org.apache.hello_world_soap_action.WrappedGreeter;
    +
    +@WebService(endpointInterface = "org.apache.hello_world_soap_action.WrappedGreeter", 
    +            serviceName = "WrappedSOAPService")
    +@SOAPBinding(use = SOAPBinding.Use.ENCODED)
    +public class WrappedEncodedSoapActionGreeterImpl implements WrappedGreeter {
    +
    +    public String sayHiRequestWrapped(String in) {
    +        return "sayHi";
    +    }
    +
    +    public String sayHiRequest2Wrapped(String in) {
    +        return "sayHi2";
    +    }
    +
    +}
    
  • systests/uncategorized/src/test/java/org/apache/cxf/systest/soap/WrappedSoapActionGreeterImpl.java+38 0 added
    @@ -0,0 +1,38 @@
    +/**
    + * 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.cxf.systest.soap;
    +
    +import javax.jws.WebService;
    +
    +import org.apache.hello_world_soap_action.WrappedGreeter;
    +
    +@WebService(endpointInterface = "org.apache.hello_world_soap_action.WrappedGreeter", 
    +            serviceName = "WrappedSOAPService")
    +public class WrappedSoapActionGreeterImpl implements WrappedGreeter {
    +
    +    public String sayHiRequestWrapped(String in) {
    +        return "sayHi";
    +    }
    +
    +    public String sayHiRequest2Wrapped(String in) {
    +        return "sayHi2";
    +    }
    +
    +}
    
  • testutils/src/main/resources/wsdl/hello_world_soap_action.wsdl+115 0 modified
    @@ -26,6 +26,7 @@
       xmlns:jms="http://cxf.apache.org/transports/jms"
       xmlns:tns="http://apache.org/hello_world_soap_action"
       xmlns:x1="http://apache.org/hello_world_soap_action/types"
    +  xmlns:x2="http://apache.org/hello_world_soap_action/types/wrapped"
       xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
       targetNamespace="http://apache.org/hello_world_soap_action"
       name="HelloWorld">
    @@ -37,6 +38,36 @@
           <element name="text" type="xsd:string" />
           <element name="text2" type="xsd:string" />
         </schema>
    +    <xsd:schema targetNamespace="http://apache.org/hello_world_soap_action/types/wrapped">
    +            <xsd:element name="sayHiRequestWrapped">
    +                <xsd:complexType>
    +                    <xsd:sequence>
    +                        <xsd:element name="wrappedText" type="xsd:string" />
    +                    </xsd:sequence>
    +                </xsd:complexType>
    +            </xsd:element>
    +            <xsd:element name="sayHiResponseWrapped">
    +                <xsd:complexType>
    +                    <xsd:sequence>
    +                        <xsd:element name="wrappedTextResponse" type="xsd:string" />
    +                    </xsd:sequence>
    +                </xsd:complexType>
    +            </xsd:element>
    +            <xsd:element name="sayHiRequest2Wrapped">
    +                <xsd:complexType>
    +                    <xsd:sequence>
    +                        <xsd:element name="wrappedText" type="xsd:string" />
    +                    </xsd:sequence>
    +                </xsd:complexType>
    +            </xsd:element>
    +            <xsd:element name="sayHiResponse2Wrapped">
    +                <xsd:complexType>
    +                    <xsd:sequence>
    +                        <xsd:element name="wrappedTextResponse" type="xsd:string" />
    +                    </xsd:sequence>
    +                </xsd:complexType>
    +            </xsd:element>
    +        </xsd:schema>
       </wsdl:types>
       <wsdl:message name="sayHiRequest">
         <wsdl:part name="in" element="x1:text" />
    @@ -50,6 +81,19 @@
       <wsdl:message name="sayHiResponse2">
         <wsdl:part name="out" element="x1:text" />
       </wsdl:message>
    +  
    +  <wsdl:message name="sayHiRequestWrapped">
    +        <wsdl:part element="x2:sayHiRequestWrapped" name="parameters" />
    +  </wsdl:message>
    +  <wsdl:message name="sayHiResponseWrapped">
    +        <wsdl:part element="x2:sayHiResponseWrapped" name="parameters" />
    +  </wsdl:message>
    +  <wsdl:message name="sayHiRequest2Wrapped">
    +        <wsdl:part element="x2:sayHiRequest2Wrapped" name="parameters" />
    +  </wsdl:message>
    +  <wsdl:message name="sayHiResponse2Wrapped">
    +        <wsdl:part element="x2:sayHiResponse2Wrapped" name="parameters" />
    +  </wsdl:message>
     
       <wsdl:portType name="Greeter">
         <wsdl:operation name="sayHi">
    @@ -63,6 +107,19 @@
         </wsdl:operation>
     
       </wsdl:portType>
    +  
    +  <wsdl:portType name="WrappedGreeter">
    +        <wsdl:operation name="sayHiRequestWrapped">
    +            <wsdl:input message="tns:sayHiRequestWrapped" />
    +            <wsdl:output message="tns:sayHiResponseWrapped" />
    +        </wsdl:operation>
    +        
    +        <wsdl:operation name="sayHiRequest2Wrapped">
    +            <wsdl:input message="tns:sayHiRequest2Wrapped" />
    +            <wsdl:output message="tns:sayHiResponse2Wrapped" />
    +        </wsdl:operation>
    +  </wsdl:portType>
    +  
       <wsdl:binding name="Greeter_SOAPBinding" type="tns:Greeter">
         <soap:binding style="document"
           transport="http://schemas.xmlsoap.org/soap/http" />
    @@ -86,6 +143,7 @@
         </wsdl:operation>
     
       </wsdl:binding>
    +  
       <wsdl:binding name="Greeter_SOAP12Binding" type="tns:Greeter">
         <soap12:binding style="document"
           transport="http://www.w3.org/2003/05/soap/bindings/HTTP/" />
    @@ -109,6 +167,53 @@
         </wsdl:operation>
         
       </wsdl:binding>
    +  
    +  <wsdl:binding name="Greeter_WrappedSOAPBinding" type="tns:WrappedGreeter">
    +        <soap:binding style="document"
    +            transport="http://schemas.xmlsoap.org/soap/http" />
    +        <wsdl:operation name="sayHiRequestWrapped">
    +            <soap:operation soapAction="SAY_HI_1" />
    +            <wsdl:input>
    +                <soap:body use="literal" />
    +            </wsdl:input>
    +            <wsdl:output>
    +                <soap:body use="literal" />
    +            </wsdl:output>
    +        </wsdl:operation>
    +        <wsdl:operation name="sayHiRequest2Wrapped">
    +            <soap:operation soapAction="SAY_HI_2" />
    +            <wsdl:input>
    +                <soap:body use="literal" />
    +            </wsdl:input>
    +            <wsdl:output>
    +                <soap:body use="literal" />
    +            </wsdl:output>
    +        </wsdl:operation>
    +  </wsdl:binding>     
    +  
    +  <wsdl:binding name="Greeter_WrappedSOAP12Binding" type="tns:WrappedGreeter">
    +        <soap12:binding style="document"
    +            transport="http://www.w3.org/2003/05/soap/bindings/HTTP/" />
    +        <wsdl:operation name="sayHiRequestWrapped">
    +            <soap12:operation soapAction="SAY_HI_1" />
    +            <wsdl:input>
    +                <soap12:body use="literal" />
    +            </wsdl:input>
    +            <wsdl:output>
    +                <soap12:body use="literal" />
    +            </wsdl:output>
    +        </wsdl:operation>
    +        <wsdl:operation name="sayHiRequest2Wrapped">
    +            <soap12:operation soapAction="SAY_HI_2" />
    +            <wsdl:input>
    +                <soap12:body use="literal" />
    +            </wsdl:input>
    +            <wsdl:output>
    +                <soap12:body use="literal" />
    +            </wsdl:output>
    +        </wsdl:operation>
    +  </wsdl:binding>     
    +  
       <wsdl:service name="SOAPService">
         <wsdl:port name="SoapPort" binding="tns:Greeter_SOAPBinding">
           <soap:address
    @@ -121,4 +226,14 @@
             location="http://localhost:9001/SOAPDocLitService/Soap12Port" />
         </wsdl:port>
       </wsdl:service>
    +  <wsdl:service name="WrappedSOAPService">
    +      <wsdl:port name="WrappedSoapPort" binding="tns:Greeter_WrappedSOAPBinding">
    +            <soap:address location="http://localhost:9001/SOAPDocLitService/WrappedSoapPort" />
    +      </wsdl:port>
    +  </wsdl:service>
    +  <wsdl:service name="WrappedSOAP12Service">
    +      <wsdl:port name="WrappedSoap12Port" binding="tns:Greeter_WrappedSOAP12Binding">
    +            <soap:address location="http://localhost:9001/SOAPDocLitService/WrappedSoap12Port" />
    +      </wsdl:port>
    +  </wsdl:service>
     </wsdl:definitions>
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

33

News mentions

0

No linked articles in our index yet.