diff --git a/debian/changelog b/debian/changelog index bf8c52a..a6a98b1 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,28 @@ +libxstream-java (1.4.11.1-1+deb9u2) stretch-security; urgency=high + + * Non-maintainer upload by the LTS team. + * Fix CVE-2021-21341 to CVE-2021-21351: + In XStream there is a vulnerability which may allow a remote attacker to + load and execute arbitrary code from a remote host only by manipulating the + processed input stream. + + The type hierarchies for java.io.InputStream, java.nio.channels.Channel, + javax.activation.DataSource and javax.sql.rowsel.BaseRowSet are now + blacklisted as well as the individual types + com.sun.corba.se.impl.activation.ServerTableEntry, + com.sun.tools.javac.processing.JavacProcessingEnvironment$NameProcessIterator, + sun.awt.datatransfer.DataTransferer$IndexOrderComparator, and + sun.swing.SwingLazyValue. Additionally the internal type + Accessor$GetterSetterReflection of JAXB, the internal types + MethodGetter$PrivilegedGetter and ServiceFinder$ServiceNameIterator of + JAX-WS, all inner classes of javafx.collections.ObservableList and an + internal ClassLoader used in a private BCEL copy 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. + + -- Markus Koschany Sat, 03 Apr 2021 19:17:05 +0200 + libxstream-java (1.4.11.1-1+deb9u1) stretch-security; urgency=high * Team upload. diff --git a/debian/patches/CVE-2021-21341-to-CVE-2021-21351.patch b/debian/patches/CVE-2021-21341-to-CVE-2021-21351.patch new file mode 100644 index 0000000..27229b3 --- /dev/null +++ b/debian/patches/CVE-2021-21341-to-CVE-2021-21351.patch @@ -0,0 +1,144 @@ +From: Markus Koschany +Date: Sat, 3 Apr 2021 20:47:22 +0200 +Subject: CVE-2021-21341-to-CVE-2021-21351 + +Bug-Debian: https://bugs.debian.org/985843 +Origin: https://github.com/x-stream/xstream/commit/d5e51177634afea7213b9dc2d21f101d2e258db9 +--- + .../src/java/com/thoughtworks/xstream/XStream.java | 31 +++++++++++++--- + .../acceptance/SecurityVulnerabilityTest.java | 43 ++++++++++++++++++++++ + 2 files changed, 69 insertions(+), 5 deletions(-) + +diff --git a/xstream/src/java/com/thoughtworks/xstream/XStream.java b/xstream/src/java/com/thoughtworks/xstream/XStream.java +index 1d28088..5fcf401 100644 +--- a/xstream/src/java/com/thoughtworks/xstream/XStream.java ++++ b/xstream/src/java/com/thoughtworks/xstream/XStream.java +@@ -1,6 +1,6 @@ + /* + * Copyright (C) 2003, 2004, 2005, 2006 Joe Walnes. +- * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2020 XStream Committers. ++ * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2020, 2021 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD +@@ -36,7 +36,6 @@ import java.net.URL; + import java.nio.charset.Charset; + import java.text.DecimalFormatSymbols; + import java.util.ArrayList; +-import java.util.Arrays; + import java.util.BitSet; + import java.util.Calendar; + import java.util.Collection; +@@ -354,9 +353,14 @@ public class XStream { + + private static final String ANNOTATION_MAPPER_TYPE = "com.thoughtworks.xstream.mapper.AnnotationMapper"; + private static final Pattern IGNORE_ALL = Pattern.compile(".*"); ++ private static final Pattern GETTER_SETTER_REFLECTION = Pattern.compile(".*\\$GetterSetterReflection"); ++ private static final Pattern PRIVILEGED_GETTER = Pattern.compile(".*\\$PrivilegedGetter"); + private static final Pattern LAZY_ITERATORS = Pattern.compile(".*\\$LazyIterator"); ++ private static final Pattern JAXWS_ITERATORS = Pattern.compile(".*\\$ServiceNameIterator"); ++ private static final Pattern JAVAFX_OBSERVABLE_LIST__ = Pattern.compile( ++ "javafx\\.collections\\.ObservableList\\$.*"); + private static final Pattern JAVAX_CRYPTO = Pattern.compile("javax\\.crypto\\..*"); +- private static final Pattern JAXWS_FILE_STREAM = Pattern.compile(".*\\.ReadAllStream\\$FileStream"); ++ private static final Pattern BCEL_CL = Pattern.compile(".*\\.bcel\\..*\\.util\\.ClassLoader"); + + /** + * Constructs a default XStream. +@@ -703,18 +707,35 @@ public class XStream { + "java.beans.EventHandler", + "java.lang.ProcessBuilder", + "javax.imageio.ImageIO$ContainsFilter", +- "jdk.nashorn.internal.objects.NativeString"}); ++ "jdk.nashorn.internal.objects.NativeString", // ++ "com.sun.corba.se.impl.activation.ServerTableEntry", // ++ "com.sun.tools.javac.processing.JavacProcessingEnvironment$NameProcessIterator", // ++ "sun.awt.datatransfer.DataTransferer$IndexOrderComparator", // ++ "sun.swing.SwingLazyValue"}); ++ denyTypesByRegExp(new Pattern[]{ ++ LAZY_ITERATORS, GETTER_SETTER_REFLECTION, PRIVILEGED_GETTER, JAVAX_CRYPTO, JAXWS_ITERATORS, ++ JAVAFX_OBSERVABLE_LIST__, BCEL_CL}); ++ denyTypeHierarchy(InputStream.class); ++ denyTypeHierarchyDynamically("java.nio.channels.Channel"); ++ denyTypeHierarchyDynamically("javax.activation.DataSource"); ++ denyTypeHierarchyDynamically("javax.sql.rowset.BaseRowSet"); + denyTypes(new Class[]{ + java.lang.ProcessBuilder.class, + jdk.nashorn.internal.objects.NativeString.class, + java.beans.EventHandler.class, + java.lang.ProcessBuilder.class, + java.lang.Void.class, void.class }); +- denyTypesByRegExp(new Pattern[] {LAZY_ITERATORS, JAVAX_CRYPTO, JAXWS_FILE_STREAM}); + allowTypeHierarchy(Exception.class); + securityInitialized = false; + } + ++ private void denyTypeHierarchyDynamically(String className) { ++ Class type = JVM.loadClassForName(className); ++ if (type != null) { ++ denyTypeHierarchy(type); ++ } ++ } ++ + /** + * Setup the security framework of a XStream instance. + *

+diff --git a/xstream/src/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java b/xstream/src/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java +index 36b61a1..77c2bb9 100644 +--- a/xstream/src/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java ++++ b/xstream/src/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java +@@ -11,6 +11,7 @@ + package com.thoughtworks.acceptance; + + import java.beans.EventHandler; ++import java.io.ByteArrayInputStream; + import java.io.File; + import java.io.FileOutputStream; + import java.io.IOException; +@@ -271,4 +272,46 @@ public class SecurityVulnerabilityTest extends AbstractAcceptanceTest { + } + } + } ++ ++ public void testCannotInjectManipulatedByteArryInputStream() { ++ xstream.alias("bais", ByteArrayInputStream.class); ++ System.out.println(Integer.MAX_VALUE); ++ final String xml = "" ++ + "\n" ++ + " \n" ++ + " -2147483648\n" ++ + " 0\n" ++ + " 0\n" ++ + ""; ++ ++ try { ++ xstream.fromXML(xml); ++ fail("Thrown " + ForbiddenClassException.class.getName() + " expected"); ++ } catch (final ForbiddenClassException e) { ++ assertEquals(e.getMessage(),ByteArrayInputStream.class.getName()); ++ } ++ } ++ ++ public void testExplicitlyUnmarshalEndlessByteArryInputStream() { ++ xstream.alias("bais", ByteArrayInputStream.class); ++ xstream.allowTypes(new Class[]{ByteArrayInputStream.class}); ++ ++ final String xml = "" ++ + "\n" ++ + " \n" ++ + " -2147483648\n" ++ + " 0\n" ++ + " 0\n" ++ + ""; ++ ++ final byte[] data = new byte[10]; ++ final ByteArrayInputStream bais = (ByteArrayInputStream)xstream.fromXML(xml); ++ int i = 5; ++ while(bais.read(data, 0, 10) == 0) { ++ if (--i == 0) { ++ break; ++ } ++ } ++ assertEquals("Unlimited reads of ByteArrayInputStream returning 0 bytes expected", 0, i); ++ } + } diff --git a/debian/patches/series b/debian/patches/series index 7d78f18..a202d8d 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -2,3 +2,4 @@ CVE-2020-26217.patch CVE-2020-26258.patch CVE-2020-26259.patch +CVE-2021-21341-to-CVE-2021-21351.patch