I made Jira issue concerning this problem 
http://jira.codehaus.org/browse/XFIRE-1101 but I decided to ask
here too if someone would know workaround to avoid this problem.

I have used XFire 1.2.6 and Aegis & inheritance 
(http://xfire.codehaus.org/Aegis+Inheritance) in my SOAP service.
I noticed that usage of inheritance has made my SOAP service unsafe because 
SOAP client can easily
crash whole application server running my SOAP service using non-existing type 
in xsi:type attribute in SOAP request.

I made a simple example to illustrate the problem based on spring (Echo) 
example coming with XFire distribution.
You can download the example package from Jira http://jira.codehaus.org/secure/attachment/30450/Echo.zip (XFire libraries removed to save space). Original Echo example had one echo method that receives String parameter and returns same String back to client. I just modified it to pass java.lang.Object instead of String.

So Echo interface looks like this:

public interface Echo
{
        Object echo(Object in);
}

And implementation class looks like this:

public class EchoImpl implements Echo
{
        public Object echo(Object in)
        {
                System.out.println("Input data: " + in);
                System.out.println("Type of input data: " + 
in.getClass().getName());
                return in;
        }
}

Now following SOAP request works fine:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/";
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xmlns:xsd="http://www.w3.org/2001/XMLSchema";>
        <soap:Body>
                <echo xmlns="http://example.spring.xfire.codehaus.org";>
                        <in0 xsi:type="xsd:string">42</in0>
                </echo>
        </soap:Body>
</soap:Envelope>

SOAP service writes following output as expected:
[11/7/07 17:22:23:937 EET] 10596e5e SystemOut O Input data: 42
[11/7/07 17:22:23:937 EET] 10596e5e SystemOut O Type of input data: 
java.lang.String

And client receives following response:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"; xmlns:xsd="http://www.w3.org/2001/XMLSchema"; xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";>
   <soap:Body>
      <ns1:echoResponse xmlns:ns1="http://example.spring.xfire.codehaus.org";>
         <ns1:out xsi:type="xsd:string">42</ns1:out>
      </ns1:echoResponse>
   </soap:Body>
</soap:Envelope>

Now if I change type of passed argument to xsi:type="xsd:String" where type name contains spelling error (starts with uppercase letter instead of lowercase letter, something that can easily happen when SOAP request is written by human user) then XFire ends up to infinite recursion and finally causes java.lang.StackOverflowError and whole application server crashes (actually not in the first time but after second similar request). Here is the stacktrace from such
case:

[11/7/07 17:25:52:967 EET] 10596e5e WebGroup E SRVE0026E: [Servlet Error]-[Error occured during request processing: null]: java.lang.StackOverflowError
at java.lang.String.hashCode(String.java(Compiled Code))
at 
com.ctc.wstx.sr.NsAttributeCollector.getValue(NsAttributeCollector.java(Compiled
 Code))
at 
com.ctc.wstx.sr.BasicStreamReader.getAttributeValue(BasicStreamReader.java(Compiled
 Code))
at 
org.codehaus.xfire.util.stax.DepthXMLStreamReader.getAttributeValue(DepthXMLStreamReader.java(Compiled
 Code))
at 
org.codehaus.xfire.util.stax.DepthXMLStreamReader.getAttributeValue(DepthXMLStreamReader.java(Inlined
 Compiled Code))
at 
org.codehaus.xfire.aegis.stax.ElementReader.getAttributeReader(ElementReader.java(Compiled
 Code))

... (ObjectType.readObject method end up to the infinite loop, lots of stack trace elements identical to ones in below removed from here)

at 
org.codehaus.xfire.aegis.type.basic.ObjectType.readObject(ObjectType.java:133)
at 
org.codehaus.xfire.aegis.type.basic.ObjectType.readObject(ObjectType.java:133)
at 
org.codehaus.xfire.aegis.type.basic.ObjectType.readObject(ObjectType.java:133)
at 
org.codehaus.xfire.aegis.type.basic.ObjectType.readObject(ObjectType.java:133)
at 
org.codehaus.xfire.aegis.type.basic.ObjectType.readObject(ObjectType.java:133)
at 
org.codehaus.xfire.aegis.type.basic.ObjectType.readObject(ObjectType.java:133)
at 
org.codehaus.xfire.aegis.type.basic.ObjectType.readObject(ObjectType.java:133)
at 
org.codehaus.xfire.aegis.AegisBindingProvider.readParameter(AegisBindingProvider.java:169)
at 
org.codehaus.xfire.service.binding.AbstractBinding.read(AbstractBinding.java:206)
at 
org.codehaus.xfire.service.binding.WrappedBinding.readMessage(WrappedBinding.java:51)
at 
org.codehaus.xfire.soap.handler.SoapBodyHandler.invoke(SoapBodyHandler.java:42)
at org.codehaus.xfire.handler.HandlerPipeline.invoke(HandlerPipeline.java:131)
at 
org.codehaus.xfire.transport.DefaultEndpoint.onReceive(DefaultEndpoint.java:64)
at org.codehaus.xfire.transport.AbstractChannel.receive(AbstractChannel.java:38)
at 
org.codehaus.xfire.transport.http.XFireServletController.invoke(XFireServletController.java:304)
at 
org.codehaus.xfire.transport.http.XFireServletController.doService(XFireServletController.java:129)
at 
org.codehaus.xfire.spring.remoting.XFireServletControllerAdapter.handleRequest(XFireServletControllerAdapter.java:67)
at 
org.codehaus.xfire.spring.remoting.XFireExporter.handleRequest(XFireExporter.java:48)
at 
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:44)
at 
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:717)
at 
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:658)
at 
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:392)
at 
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:357)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:760)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at 
com.ibm.ws.webcontainer.servlet.StrictServletInstance.doService(StrictServletInstance.java:110)
at 
com.ibm.ws.webcontainer.servlet.StrictLifecycleServlet._service(StrictLifecycleServlet.java:174)
at 
com.ibm.ws.webcontainer.servlet.IdleServletState.service(StrictLifecycleServlet.java:313)
at 
com.ibm.ws.webcontainer.servlet.StrictLifecycleServlet.service(StrictLifecycleServlet.java:116)
at 
com.ibm.ws.webcontainer.servlet.ServletInstance.service(ServletInstance.java:283)
at 
com.ibm.ws.webcontainer.servlet.ValidServletReferenceState.dispatch(ValidServletReferenceState.java:42)
at 
com.ibm.ws.webcontainer.servlet.ServletInstanceReference.dispatch(ServletInstanceReference.java:40)
at 
com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.handleWebAppDispatch(WebAppRequestDispatcher.java:1019)
at 
com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.dispatch(WebAppRequestDispatcher.java:592)
at 
com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.forward(WebAppRequestDispatcher.java:204)
at com.ibm.ws.webcontainer.srt.WebAppInvoker.doForward(WebAppInvoker.java:125)
at 
com.ibm.ws.webcontainer.srt.WebAppInvoker.handleInvocationHook(WebAppInvoker.java:286)
at 
com.ibm.ws.webcontainer.cache.invocation.CachedInvocation.handleInvocation(CachedInvocation.java:71)
at 
com.ibm.ws.webcontainer.cache.invocation.CacheableInvocationContext.invoke(CacheableInvocationContext.java:116)
at 
com.ibm.ws.webcontainer.srp.ServletRequestProcessor.dispatchByURI(ServletRequestProcessor.java:186)
at 
com.ibm.ws.webcontainer.oselistener.OSEListenerDispatcher.service(OSEListener.java:334)
at 
com.ibm.ws.webcontainer.http.HttpConnection.handleRequest(HttpConnection.java:56)
at com.ibm.ws.http.HttpConnection.readAndHandleRequest(HttpConnection.java:615)
at com.ibm.ws.http.HttpConnection.run(HttpConnection.java:439)
at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:912)

On my opinion this is quite serious problem since SOAP service cannot trust 
that client always sends valid SOAP request.
Shouldn't XFire notice that type defined in request is not defined in WSDL or 
XMLSchema and return SOAP Fault?

Is there any quick workaround to prevent this happening assuming that I don't have time to implement my SOAP service from scratch using different approach?

--
Jari Kujansuu, [EMAIL PROTECTED]


---------------------------------------------------------------------
To unsubscribe from this list please visit:

   http://xircles.codehaus.org/manage_email

Reply via email to