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