Is it possible to unregister the DynamicProxyConverter using the SpringOXM wrapper

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Is it possible to unregister the DynamicProxyConverter using the SpringOXM wrapper

Alvaro Muñoz
Hi,

I found that using the DynamicProxyConverter can be a security issue that can lead to remote code execution.
I dont know if it is possible to unregister it as I can see no unregisterConverters method in the XStream class but I would like to use XStream SpringOXM wrapper for a RESTFul API, so I would like to unregister it using the SpringOXM wrapper, is it possible?

Thanks,

Alvaro
Reply | Threaded
Open this post in threaded view
|

Re: Is it possible to unregister the DynamicProxyConverter using the SpringOXM wrapper

Jörg Schaible-2
Hello Alvaro,

Alvaro wrote:

> Hi,
>
> I found that using the DynamicProxyConverter can be a security issue that
> can lead to remote code execution.

Can you elaborate a bit?

> I dont know if it is possible to unregister it

No.

> as I can see no
> unregisterConverters method in the XStream class

For an existing XStream instance you can only register other converters with
same or higher priority that claim to handle the same types.

As alternative you might provide a ConverterLookup as constructor parameter
that contains already all supported converters and a ConverterRegistry that
actually does nothing.

Another alternative is to overwrite XStream's setupConverter method.

> but I would like to use
> XStream SpringOXM wrapper for a RESTFul API, so I would like to unregister
> it using the SpringOXM wrapper, is it possible?

Sorry, I am not familiar with SpringOXM at all. Therefore I cannot say how
you configure it to use either different constructor parameters or an
instance of a derived XStream type.

Cheers,
Jörg


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

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: Is it possible to unregister the DynamicProxyConverter using the SpringOXM wrapper

Alvaro Muñoz
Lets say you have a Contact Interface and a ContactImpl class.

Contact c = (Contact) xstream.fromXML(xml);
and xml is:

      <dynamic-proxy>
      <interface>org.company.model.Contact</interface>
      <handler class="java.beans.EventHandler">
          <target class="java.lang.ProcessBuilder">
              <command>
                   <string>calc.exe</string>
              </command>
          </target>
          <action>start</action>
      </handler>
      </dynamic-proxy>

Then as soon as the code calls any method on the Contact instace, the payload gets executed (eg: contact.getFirstName() )


SpringOXM has a wrapper for XStream (org.springframework.oxm.xstream.XStreamMarshaller) that enables the unmarshalling of objects from XML format.
This SpringOXM module is used by SpringMVC when building RESTFul APIs.
My concern is that an attacker can sends a malicious crafted XML that results in remote code execution in the case that the server is expecting an object that implements an interface.

I would love to be able to disable the DynamicProxyconverter in simple fashion and expose that method to the SpringgOXM wrapper so it can be safely used for RESTFul APIs.

Thanks,
A

Un saludo,

Alvaro


On Wed, Jul 17, 2013 at 6:49 PM, Jörg Schaible <[hidden email]> wrote:
Hello Alvaro,

Alvaro wrote:

> Hi,
>
> I found that using the DynamicProxyConverter can be a security issue that
> can lead to remote code execution.

Can you elaborate a bit?

> I dont know if it is possible to unregister it

No.

> as I can see no
> unregisterConverters method in the XStream class

For an existing XStream instance you can only register other converters with
same or higher priority that claim to handle the same types.

As alternative you might provide a ConverterLookup as constructor parameter
that contains already all supported converters and a ConverterRegistry that
actually does nothing.

Another alternative is to overwrite XStream's setupConverter method.

> but I would like to use
> XStream SpringOXM wrapper for a RESTFul API, so I would like to unregister
> it using the SpringOXM wrapper, is it possible?

Sorry, I am not familiar with SpringOXM at all. Therefore I cannot say how
you configure it to use either different constructor parameters or an
instance of a derived XStream type.

Cheers,
Jörg


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

    http://xircles.codehaus.org/manage_email



Reply | Threaded
Open this post in threaded view
|

Re: Re: Is it possible to unregister the DynamicProxyConverter using the SpringOXM wrapper

Jörg Schaible-2
Hi Alvaro,

Alvaro wrote:

> Lets say you have a Contact Interface and a ContactImpl class.
>
> Contact c = (Contact) xstream.fromXML(xml);
>
> and xml is:
>
>       <dynamic-proxy>
>       <interface>org.company.model.Contact</interface>
>       <handler class="java.beans.EventHandler">
>           <target class="java.lang.ProcessBuilder">
>               <command>
>                    <string>calc.exe</string>
>               </command>
>           </target>
>           <action>start</action>
>       </handler>
>       </dynamic-proxy>
>
> Then as soon as the code calls any method on the Contact instace, the
> payload gets executed (eg: contact.getFirstName() )

Ah, that one. Yes, I have seen it before, but I do not blame the dynamic
proxy by default. It's even questionable if this is a special problem with
XStream. While this *is* a security hole, it is made possible by
EventHandler's create method:

=============== %< ==============
public class Main {
    public static void main(String[] args) {
        Set<Comparable> set = new TreeSet<Comparable>();
        set.add("foo");
        set.add(EventHandler.create(Comparable.class, new
ProcessBuilder("gvim", "/home/joehni/tmp/ps-aux.txt"), "start"));
    }
}
=============== %< ==============

While this is demonstrates the problem in pure Java, you will have the same
security hole in any *scripted* environment that can call the JVM. Like
XStream you can demonstrate this also with the Java ScriptEngine or quite
any Dependency Injection container that is configured from the outside. It
is a bit like SQL injection - if you accept input you have to ensure that it
cannot be abused.

However, it is unfortunate that the JRE itself already provides such an easy
way to redirect a method call to an arbitrary method of a target, but it is
explicitly documented:
<http://docs.oracle.com/javase/7/docs/api/java/beans/EventHandler.html#create(java.lang.Class,
java.lang.Object, java.lang.String)>

There's no general solution for every use case though, but it is quite easy
to write a converter for an EventHandler or a ProcessBuilder that will throw
an Exception at deserialization time. But it still depends on the use case.
XStream cannot say if the deserialization of such an object is wrong in
general or if it is a valid element of the object graph. In the latter case
an implementation of a EventHandlerConverter might only throw an exception
if the action name does not match a method of the proxied interface.
Nevertheless, there is a reason why this functionality made it into the JRE
and an object graph with GUI objects might contain such an element with much
higher probability than expected.

Therefore I was never sure if XStream should register such a converter by
default, but it is really frightening to have such an easy possibility for
abuse.

Actually you have 3 parts in the plain JDK itself that makes this possible:
- the dynamic proxy that can be used to insert a matching replacement
- the EventHandler that translates every call into an arbitrary action
- the ProcessBuilder that supports the call of arbitrary applications

And XStream provides with the reflection-based converters the 4th part by
deserializing arbitrary objects.

> SpringOXM has a wrapper for XStream
> (org.springframework.oxm.xstream.XStreamMarshaller) that enables the
> unmarshalling of objects from XML format.
> This SpringOXM module is used by SpringMVC when building RESTFul APIs.
> My concern is that an attacker can sends a malicious crafted XML that
> results in remote code execution in the case that the server is expecting
> an object that implements an interface.
>
> I would love to be able to disable the DynamicProxyconverter in simple
> fashion and expose that method to the SpringgOXM wrapper so it can be
> safely used for RESTFul APIs.

As said, I have no knowledge about the configuration possibility of XStream
within SpringOXM.

However, in case of untrusted input, you're only on the safe side, if you
prevent XStream from using the reflection converters although it is enough
to break the action in your example by suppressing one of the 4 involved
parts. But as long as the reflection-based converters work, an attacker mind
find other ways.

This implies that you use dedicated converters for all of your objects (you
might use as a more generic alternative the JavaBeanConverter) and register
a converter that claims to convert any type with low priority, but that will
throw an exception in unmarshal. Since the reflection-based converters have
even lower priority, they're never called.

Regards,
Jörg


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

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: Re: Is it possible to unregister the DynamicProxyConverter using the SpringOXM wrapper

Alvaro Muñoz
Thanks for the quick response!

So the way to "disable" the Reflection converters is:

1 - Register a High priority converter for the beans you are expecting in your application
2 - Register a catch-all converter with higher priority than the reflection ones that will throw an exception

Is that correct?

If so, I think this can also been done for the SpringOXM wrapper since they expose the registerConverters method.

I agree that the chain of events neccessary to run arbitrary code depends on many items of the JRE but it is the Reflection Converter the one that makes it possible in the end. So it is like XStream is opening that door by default and the way to close it is not immediate. Would it be possible to not register the reflection converters by default so only users that need them do it?

Thanks again!
A

Un saludo,

Alvaro


On Thu, Jul 18, 2013 at 12:52 AM, Jörg Schaible <[hidden email]> wrote:
Hi Alvaro,

Alvaro wrote:

> Lets say you have a Contact Interface and a ContactImpl class.
>
> Contact c = (Contact) xstream.fromXML(xml);
>
> and xml is:
>
>       <dynamic-proxy>
>       <interface>org.company.model.Contact</interface>
>       <handler class="java.beans.EventHandler">
>           <target class="java.lang.ProcessBuilder">
>               <command>
>                    <string>calc.exe</string>
>               </command>
>           </target>
>           <action>start</action>
>       </handler>
>       </dynamic-proxy>
>
> Then as soon as the code calls any method on the Contact instace, the
> payload gets executed (eg: contact.getFirstName() )

Ah, that one. Yes, I have seen it before, but I do not blame the dynamic
proxy by default. It's even questionable if this is a special problem with
XStream. While this *is* a security hole, it is made possible by
EventHandler's create method:

=============== %< ==============
public class Main {
    public static void main(String[] args) {
        Set<Comparable> set = new TreeSet<Comparable>();
        set.add("foo");
        set.add(EventHandler.create(Comparable.class, new
ProcessBuilder("gvim", "/home/joehni/tmp/ps-aux.txt"), "start"));
    }
}
=============== %< ==============

While this is demonstrates the problem in pure Java, you will have the same
security hole in any *scripted* environment that can call the JVM. Like
XStream you can demonstrate this also with the Java ScriptEngine or quite
any Dependency Injection container that is configured from the outside. It
is a bit like SQL injection - if you accept input you have to ensure that it
cannot be abused.

However, it is unfortunate that the JRE itself already provides such an easy
way to redirect a method call to an arbitrary method of a target, but it is
explicitly documented:
<http://docs.oracle.com/javase/7/docs/api/java/beans/EventHandler.html#create(java.lang.Class,
java.lang.Object, java.lang.String)>

There's no general solution for every use case though, but it is quite easy
to write a converter for an EventHandler or a ProcessBuilder that will throw
an Exception at deserialization time. But it still depends on the use case.
XStream cannot say if the deserialization of such an object is wrong in
general or if it is a valid element of the object graph. In the latter case
an implementation of a EventHandlerConverter might only throw an exception
if the action name does not match a method of the proxied interface.
Nevertheless, there is a reason why this functionality made it into the JRE
and an object graph with GUI objects might contain such an element with much
higher probability than expected.

Therefore I was never sure if XStream should register such a converter by
default, but it is really frightening to have such an easy possibility for
abuse.

Actually you have 3 parts in the plain JDK itself that makes this possible:
- the dynamic proxy that can be used to insert a matching replacement
- the EventHandler that translates every call into an arbitrary action
- the ProcessBuilder that supports the call of arbitrary applications

And XStream provides with the reflection-based converters the 4th part by
deserializing arbitrary objects.

> SpringOXM has a wrapper for XStream
> (org.springframework.oxm.xstream.XStreamMarshaller) that enables the
> unmarshalling of objects from XML format.
> This SpringOXM module is used by SpringMVC when building RESTFul APIs.
> My concern is that an attacker can sends a malicious crafted XML that
> results in remote code execution in the case that the server is expecting
> an object that implements an interface.
>
> I would love to be able to disable the DynamicProxyconverter in simple
> fashion and expose that method to the SpringgOXM wrapper so it can be
> safely used for RESTFul APIs.

As said, I have no knowledge about the configuration possibility of XStream
within SpringOXM.

However, in case of untrusted input, you're only on the safe side, if you
prevent XStream from using the reflection converters although it is enough
to break the action in your example by suppressing one of the 4 involved
parts. But as long as the reflection-based converters work, an attacker mind
find other ways.

This implies that you use dedicated converters for all of your objects (you
might use as a more generic alternative the JavaBeanConverter) and register
a converter that claims to convert any type with low priority, but that will
throw an exception in unmarshal. Since the reflection-based converters have
even lower priority, they're never called.

Regards,
Jörg


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

    http://xircles.codehaus.org/manage_email



Reply | Threaded
Open this post in threaded view
|

Re: Re: Re: Is it possible to unregister the DynamicProxyConverter using the SpringOXM wrapper

Jörg Schaible-3
Hi Alvaro,

Alvaro wrote:

> Thanks for the quick response!
>
> So the way to "disable" the Reflection converters is:
>
> 1 - Register a High priority converter for the beans you are expecting in
> your application

Standard priority is already fine.

> 2 - Register a catch-all converter with higher priority than the
> reflection ones that will throw an exception

Higher or same priority. Actually it applies to ReflectionConverter (lowest
prio) and SerializableConverter (low prio).

> Is that correct?

Right.

> If so, I think this can also been done for the SpringOXM wrapper since
> they expose the registerConverters method.
>
> I agree that the chain of events neccessary to run arbitrary code depends
> on many items of the JRE but it is the Reflection Converter the one that
> makes it possible in the end. So it is like XStream is opening that door
> by default and the way to close it is not immediate. Would it be possible
> to not register the reflection converters by default so only users that
> need them do it?

Unfortunately no. It's one of XStream's key features that you actually can
marshal nearly any object graph out of the box. If we drop the
ReflectionConverter as catch all, we'll break immediately ~99% of all
existing projects using XStream.

Cheers,
Jörg


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

    http://xircles.codehaus.org/manage_email