CVE-2017-7957

Vulnerability

CVE-2017-7957: XStream can cause a Denial of Service when unmarshalling void.

Affected Versions

All versions until and including version 1.4.9 are affected, but workarounds exist.

Description

The processed stream at unmarshalling time contains type information to recreate the formerly written objects. XStream creates therefore new instances based on these type information. The crash occurs if this information advises XStream to create an instance of the primitive type void. This situation can only happen if an attacker was able to manipulate the incoming data, since such an instance does not exist and cannot be marshalled therefore in first place.

Steps to Reproduce

The simplest way to demonstrate the problem is with this snippet:

XStream xstream = new XStream();
xstream.fromXML("<void/>");

If XStream is configured to read JSON, the equivalent line is:

xstream.fromXML("{'void':null}");

However, the problematic type information can be injected at any position in the provided stream, in XML just by adding a class attribute:

xstream.fromXML("<string class='void'>Hello, world!</string>");

Impact

The vulnerability may allow a remote attacker to cause a crash on the target system resulting in a denial of service only by manipulating the processed input stream.

Workarounds

XStream contains since version 1.4.7 a security framework to prevent an attack described in CVE-2013-7285. This framework can also be used to suppress the current vulnerability by setting:

xstream.denyTypes(new Class[]{ void.class, Void.class });

Users of older XStream releases can register an own converter for the void type, that also protects against this attack:

xstream.registerConverter(new Converter() {
  public boolean canConvert(Class type) {
    return Void.class == type || void.class == type;
  }

  public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
    throw new ConversionException("Type void cannot have an instance");
  }

  public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
    throw new ConversionException("Type void cannot have an instance");
  }
}, XStream.PRIORITY_VERY_HIGH);