diff --git a/CVE-2020-26217-CVE-2017-9805.patch b/CVE-2020-26217-CVE-2017-9805.patch new file mode 100644 index 0000000000000000000000000000000000000000..c7a8ecf580b4c674862d1e7e1842f65ba7529d26 --- /dev/null +++ b/CVE-2020-26217-CVE-2017-9805.patch @@ -0,0 +1,146 @@ +From 0fec095d534126931c99fd38e9c6d41f5c685c1a Mon Sep 17 00:00:00 2001 +From: joehni +Date: Thu, 24 Sep 2020 01:56:49 +0200 +Subject: [PATCH] Fix for CVE-2017-9805 CVE-2020-26217 + +--- + .../com/thoughtworks/xstream/XStream.java | 2 +- + .../acceptance/SecurityVulnerabilityTest.java | 118 +++++++++++++----- + 2 files changed, 91 insertions(+), 29 deletions(-) + +diff --git a/xstream/src/java/com/thoughtworks/xstream/XStream.java b/xstream/src/java/com/thoughtworks/xstream/XStream.java +index 81dbf40..692243e 100644 +--- a/xstream/src/java/com/thoughtworks/xstream/XStream.java ++++ b/xstream/src/java/com/thoughtworks/xstream/XStream.java +@@ -698,7 +698,7 @@ public class XStream { + } + + addPermission(AnyTypePermission.ANY); +- denyTypes(new String[]{"java.beans.EventHandler"}); ++ denyTypes(new String[]{"java.beans.EventHandler", "javax.imageio.ImageIO$ContainsFilter"}); + denyTypesByRegExp(new Pattern[] {LAZY_ITERATORS, JAVAX_CRYPTO}); + allowTypeHierarchy(Exception.class); + securityInitialized = false; +diff --git a/xstream/src/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java b/xstream/src/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java +index 213f308..309c146 100644 +--- a/xstream/src/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java ++++ b/xstream/src/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (C) 2013, 2014, 2017, 2018 XStream Committers. ++ * Copyright (C) 2013, 2014, 2017, 2018, 2020 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD +@@ -11,14 +11,14 @@ + package com.thoughtworks.acceptance; + + import java.beans.EventHandler; ++import java.util.Iterator; + + import com.thoughtworks.xstream.XStream; + import com.thoughtworks.xstream.XStreamException; + import com.thoughtworks.xstream.converters.ConversionException; +-import com.thoughtworks.xstream.converters.reflection.ReflectionConverter; ++import com.thoughtworks.xstream.core.JVM; + import com.thoughtworks.xstream.security.AnyTypePermission; + import com.thoughtworks.xstream.security.ForbiddenClassException; +-import com.thoughtworks.xstream.security.ProxyTypePermission; + + + /** +@@ -32,8 +32,9 @@ public class SecurityVulnerabilityTest extends AbstractAcceptanceTest { + super.setUp(); + BUFFER.setLength(0); + xstream.alias("runnable", Runnable.class); +- xstream.allowTypeHierarchy(Runnable.class); +- xstream.addPermission(ProxyTypePermission.PROXIES); ++ } ++ ++ protected void setupSecurity(XStream xstream){ + } + + public void testCannotInjectEventHandler() { +@@ -58,7 +59,6 @@ public class SecurityVulnerabilityTest extends AbstractAcceptanceTest { + } + + public void testCannotInjectEventHandlerWithUnconfiguredSecurityFramework() { +- xstream = new XStream(createDriver()); + xstream.alias("runnable", Runnable.class); + final String xml = "" + + "\n" +@@ -102,6 +102,71 @@ public class SecurityVulnerabilityTest extends AbstractAcceptanceTest { + assertEquals("Executed!", BUFFER.toString()); + } + ++ public void testCannotInjectConvertImageIOContainsFilterWithUnconfiguredSecurityFramework() { ++ if (JVM.isVersion(7)) { ++ final String xml = "" ++ + "\n" ++ + " \n" ++ + " 0\n" ++ + " 1\n" ++ + " 1\n" ++ + " \n" ++ + " \n" ++ + " \n" ++ + " \n" ++ + " \n" ++ + " \n" ++ + " com.thoughtworks.acceptance.SecurityVulnerabilityTest$Exec\n" ++ + " exec\n" ++ + " \n" ++ + " \n" ++ + " exec\n" ++ + " \n" ++ + " \n" ++ + ""; ++ ++ try { ++ xstream.fromXML(xml); ++ fail("Thrown " + XStreamException.class.getName() + " expected"); ++ } catch (final XStreamException e) { ++ assertTrue(e.getMessage().indexOf("javax.imageio.ImageIO$ContainsFilter") >= 0); ++ } ++ assertEquals(0, BUFFER.length()); ++ } ++ } ++ ++ public void testExplicitlyConvertImageIOContainsFilter() { ++ if (JVM.isVersion(7)) { ++ final String xml = "" ++ + "\n" ++ + " \n" ++ + " 0\n" ++ + " 1\n" ++ + " 1\n" ++ + " \n" ++ + " \n" ++ + " \n" ++ + " \n" ++ + " \n" ++ + " \n" ++ + " com.thoughtworks.acceptance.SecurityVulnerabilityTest$Exec\n" ++ + " exec\n" ++ + " \n" ++ + " \n" ++ + " exec\n" ++ + " \n" ++ + " \n" ++ + ""; ++ ++ xstream.allowTypes(new String[]{"javax.imageio.ImageIO$ContainsFilter"}); ++ ++ final Iterator iterator = (Iterator)xstream.fromXML(xml); ++ assertEquals(0, BUFFER.length()); ++ iterator.next(); ++ assertEquals("Executed!", BUFFER.toString()); ++ } ++ } ++ + public static class Exec { + + public void exec() { +-- +2.23.0 + diff --git a/CVE-2020-26258.patch b/CVE-2020-26258.patch new file mode 100644 index 0000000000000000000000000000000000000000..9769c3384142b7823f71e5a3cbafc8e3b6ae0bd8 --- /dev/null +++ b/CVE-2020-26258.patch @@ -0,0 +1,25 @@ +From f391169515d77446e94da4836eb65adfbc8acfa2 Mon Sep 17 00:00:00 2001 +Date: Mon, 11 Jan 2021 17:32:52 +0800 +Subject: [PATCH] Fix and document CVE-2020-26258. + + +diff --git a/xstream/src/java/com/thoughtworks/xstream/XStream.java b/xstream/src/java/com/thoughtworks/xstream/XStream.java +index 692243e..8a4b104 100644 +--- a/xstream/src/java/com/thoughtworks/xstream/XStream.java ++++ b/xstream/src/java/com/thoughtworks/xstream/XStream.java +@@ -698,7 +698,11 @@ public class XStream { + } + + addPermission(AnyTypePermission.ANY); +- denyTypes(new String[]{"java.beans.EventHandler", "javax.imageio.ImageIO$ContainsFilter"}); ++ 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}); + allowTypeHierarchy(Exception.class); + securityInitialized = false; +-- +2.23.0 + diff --git a/CVE-2020-26259.patch b/CVE-2020-26259.patch new file mode 100644 index 0000000000000000000000000000000000000000..6a783ebfd00969bd2cb53af71e9da306738cea38 --- /dev/null +++ b/CVE-2020-26259.patch @@ -0,0 +1,199 @@ +From aacd07da7e2be020ef2924153838c7b0a05b596f Mon Sep 17 00:00:00 2001 +Date: Mon, 11 Jan 2021 18:00:38 +0800 +Subject: [PATCH] fix CVE-2020-26259 + + +diff --git a/pom.xml b/pom.xml +index e6fc1a1..15ff064 100644 +--- a/pom.xml ++++ b/pom.xml +@@ -546,6 +546,11 @@ + jaxb-api + ${version.javax.xml.bind.api} + ++ ++ com.sun.xml.ws ++ jaxws-rt ++ ${version.javax.xml.ws.jaxws.rt} ++ + + + org.hibernate +@@ -905,6 +910,7 @@ + 1.1.1 + 1.3.2 + 2.3.1 ++ 2.2 + 1.0.1 + 1.6 + 3.8.1 +diff --git a/xstream/pom.xml b/xstream/pom.xml +index 525425a..6543ff7 100644 +--- a/xstream/pom.xml ++++ b/xstream/pom.xml +@@ -144,6 +144,54 @@ + 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 8a4b104..57cf804 100644 +--- a/xstream/src/java/com/thoughtworks/xstream/XStream.java ++++ b/xstream/src/java/com/thoughtworks/xstream/XStream.java +@@ -356,6 +356,7 @@ public class XStream { + 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. +@@ -702,8 +703,8 @@ public class XStream { + "java.beans.EventHandler", // + "java.lang.ProcessBuilder", // + "javax.imageio.ImageIO$ContainsFilter", // +- "jdk.nashorn.internal.objects.NativeString"}); +- denyTypesByRegExp(new Pattern[] {LAZY_ITERATORS, JAVAX_CRYPTO}); ++ "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/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java b/xstream/src/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java +index 309c146..7604aa5 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; +@@ -214,4 +219,68 @@ public class SecurityVulnerabilityTest extends AbstractAcceptanceTest { + // 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(); ++ } ++ } ++ } ++ } + } +-- +2.23.0 + diff --git a/New-predefined-blacklist-avoids-vulnerability.patch b/New-predefined-blacklist-avoids-vulnerability.patch new file mode 100644 index 0000000000000000000000000000000000000000..9581947b5f467d664f981456836b829455cf112f --- /dev/null +++ b/New-predefined-blacklist-avoids-vulnerability.patch @@ -0,0 +1,164 @@ +From 51abe602e09016c8e43e91325a15226022f4da46 Mon Sep 17 00:00:00 2001 +From: joehni +Date: Wed, 2 Sep 2020 00:38:51 +0200 +Subject: [PATCH] New predefined blacklist avoids vulnerability due to improper + setup of the security framework. Closes #207. + +--- + .../com/thoughtworks/xstream/XStream.java | 37 +++++-------------- + .../acceptance/SecurityVulnerabilityTest.java | 29 +++++++++++++-- + 2 files changed, 36 insertions(+), 30 deletions(-) + +diff --git a/xstream/src/java/com/thoughtworks/xstream/XStream.java b/xstream/src/java/com/thoughtworks/xstream/XStream.java +index 4eb2e33a..72e32c6e 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 XStream Committers. ++ * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2020 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD +@@ -36,6 +36,7 @@ + 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; +@@ -65,10 +66,8 @@ + import com.thoughtworks.xstream.converters.ConverterLookup; + import com.thoughtworks.xstream.converters.ConverterRegistry; + import com.thoughtworks.xstream.converters.DataHolder; +-import com.thoughtworks.xstream.converters.MarshallingContext; + import com.thoughtworks.xstream.converters.SingleValueConverter; + import com.thoughtworks.xstream.converters.SingleValueConverterWrapper; +-import com.thoughtworks.xstream.converters.UnmarshallingContext; + import com.thoughtworks.xstream.converters.basic.BigDecimalConverter; + import com.thoughtworks.xstream.converters.basic.BigIntegerConverter; + import com.thoughtworks.xstream.converters.basic.BooleanConverter; +@@ -355,6 +354,8 @@ + + private static final String ANNOTATION_MAPPER_TYPE = "com.thoughtworks.xstream.mapper.AnnotationMapper"; + 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\\..*"); + + /** + * Constructs a default XStream. +@@ -697,6 +698,9 @@ protected void setupSecurity() { + } + + addPermission(AnyTypePermission.ANY); ++ denyTypes(new String[]{"java.beans.EventHandler"}); ++ denyTypesByRegExp(new Pattern[] {LAZY_ITERATORS, JAVAX_CRYPTO}); ++ allowTypeHierarchy(Exception.class); + securityInitialized = false; + } + +@@ -962,7 +966,6 @@ protected void setupConverters() { + registerConverter( + new SerializableConverter(mapper, reflectionProvider, classLoaderReference), PRIORITY_LOW); + registerConverter(new ExternalizableConverter(mapper, classLoaderReference), PRIORITY_LOW); +- registerConverter(new InternalBlackList(), PRIORITY_LOW); + + registerConverter(new NullConverter(), PRIORITY_VERY_HIGH); + registerConverter(new IntConverter(), PRIORITY_NORMAL); +@@ -1482,7 +1485,8 @@ public Object unmarshal(HierarchicalStreamReader reader, Object root, DataHolder + try { + if (!securityInitialized && !securityWarningGiven) { + securityWarningGiven = true; +- System.err.println("Security framework of XStream not initialized, XStream is probably vulnerable."); ++ System.err ++ .println("Security framework of XStream not explicitly initialized, using predefined black list on your own risk."); + } + return marshallingStrategy.unmarshal( + root, reader, dataHolder, converterLookup, mapper); +@@ -2360,7 +2364,7 @@ public void autodetectAnnotations(boolean mode) { + */ + public void addPermission(TypePermission permission) { + if (securityMapper != null) { +- securityInitialized = true; ++ securityInitialized |= permission.equals(NoTypePermission.NONE) || permission.equals(AnyTypePermission.ANY); + securityMapper.addPermission(permission); + } + } +@@ -2539,25 +2543,4 @@ public InitializationException(String message) { + super(message); + } + } +- +- private class InternalBlackList implements Converter { +- +- public boolean canConvert(final Class type) { +- return (type == void.class || type == Void.class) +- || (!securityInitialized +- && type != null +- && (type.getName().equals("java.beans.EventHandler") +- || type.getName().endsWith("$LazyIterator") +- || type.getName().startsWith("javax.crypto."))); +- } +- +- public void marshal(final Object source, final HierarchicalStreamWriter writer, +- final MarshallingContext context) { +- throw new ConversionException("Security alert. Marshalling rejected."); +- } +- +- public Object unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context) { +- throw new ConversionException("Security alert. Unmarshalling rejected."); +- } +- } + } +diff --git a/xstream/src/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java b/xstream/src/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java +index c7d7ebe4..18379276 100644 +--- a/xstream/src/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java ++++ b/xstream/src/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java +@@ -16,6 +16,7 @@ + import com.thoughtworks.xstream.XStreamException; + import com.thoughtworks.xstream.converters.ConversionException; + import com.thoughtworks.xstream.converters.reflection.ReflectionConverter; ++import com.thoughtworks.xstream.security.AnyTypePermission; + import com.thoughtworks.xstream.security.ForbiddenClassException; + import com.thoughtworks.xstream.security.ProxyTypePermission; + +@@ -108,6 +109,15 @@ public void exec() { + } + } + ++ public void testInstanceOfVoid() { ++ try { ++ xstream.fromXML(""); ++ fail("Thrown " + ConversionException.class.getName() + " expected"); ++ } catch (final ConversionException e) { ++ assertEquals("void", e.get("construction-type")); ++ } ++ } ++ + public void testDeniedInstanceOfVoid() { + try { + xstream.fromXML(""); +@@ -123,7 +133,20 @@ public void testAllowedInstanceOfVoid() { + xstream.fromXML(""); + fail("Thrown " + ConversionException.class.getName() + " expected"); + } catch (final ConversionException e) { +- assertEquals("void", e.get("required-type")); ++ assertEquals("void", e.get("construction-type")); ++ } ++ } ++ ++ public static class LazyIterator { ++ } ++ ++ public void testInstanceOfLazyIterator() { ++ xstream.alias("lazy-iterator", LazyIterator.class); ++ try { ++ xstream.fromXML(""); ++ fail("Thrown " + ForbiddenClassException.class.getName() + " expected"); ++ } catch (final ForbiddenClassException e) { ++ // OK + } + } + } diff --git a/xstream.spec b/xstream.spec index 00f92c22e545ba06abbd5b8c4c4b6e9c8ac82a33..0370c00087334cbea6ed6fdfcd68b191633bea08 100644 --- a/xstream.spec +++ b/xstream.spec @@ -1,12 +1,17 @@ %bcond_with jp_minimal Name: xstream Version: 1.4.11.1 -Release: 1 +Release: 3 Summary: Java XML serialization library License: BSD URL: http://x-stream.github.io/ BuildArch: noarch Source0: http://repo1.maven.org/maven2/com/thoughtworks/xstream/xstream-distribution/%{version}/xstream-distribution-%{version}-src.zip +Patch0: New-predefined-blacklist-avoids-vulnerability.patch +Patch1: CVE-2020-26217-CVE-2017-9805.patch +Patch2: CVE-2020-26258.patch +Patch3: CVE-2020-26259.patch + BuildRequires: maven-local mvn(cglib:cglib) mvn(dom4j:dom4j) mvn(javax.xml.bind:jaxb-api) BuildRequires: mvn(joda-time:joda-time) mvn(net.sf.kxml:kxml2-min) BuildRequires: mvn(org.apache.felix:maven-bundle-plugin) @@ -67,6 +72,11 @@ Parent POM for xstream. %prep %setup -qn xstream-%{version} +%patch0 -p1 +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 + find . -name "*.class" -print -delete find . -name "*.jar" -print -delete %pom_disable_module xstream-distribution @@ -124,6 +134,12 @@ rm xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/ %license LICENSE.txt %changelog +* Mon Jan 11 2021 wangyue-1.4.11.1-3 +- Fix CVE-2020-26258 CVE-2020-26259 + +* Sat Dec 12 2020 huanghaitao - 1.4.11.1-2 +- Fix CVE-2020-26217 CVE-2017-9805 + * Fri Aug 14 2020 yaokai - 1.4.11.1-1 - upgrade to 1.4.11.1-1