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