1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
|
From: Markus Koschany <apo@debian.org>
Date: Wed, 11 Jan 2023 13:57:58 +0100
Subject: CVE-2022-41966
Bug-Debian: https://bugs.debian.org/1027754
Origin: https://github.com/x-stream/xstream/commit/e9151f221b4969fb15b1e946d5d61dcdd459a391
---
.../src/java/com/thoughtworks/xstream/XStream.java | 8 +++--
.../security/AbstractSecurityException.java | 29 ++++++++++++++++++
.../security/InputManipulationException.java | 27 +++++++++++++++++
.../acceptance/SecurityVulnerabilityTest.java | 35 +++++++++++++++++++++-
4 files changed, 96 insertions(+), 3 deletions(-)
create mode 100644 xstream/src/java/com/thoughtworks/xstream/security/AbstractSecurityException.java
create mode 100644 xstream/src/java/com/thoughtworks/xstream/security/InputManipulationException.java
diff --git a/xstream/src/java/com/thoughtworks/xstream/XStream.java b/xstream/src/java/com/thoughtworks/xstream/XStream.java
index 129be1c..24c51cf 100644
--- a/xstream/src/java/com/thoughtworks/xstream/XStream.java
+++ b/xstream/src/java/com/thoughtworks/xstream/XStream.java
@@ -162,6 +162,7 @@ import com.thoughtworks.xstream.security.RegExpTypePermission;
import com.thoughtworks.xstream.security.TypeHierarchyPermission;
import com.thoughtworks.xstream.security.TypePermission;
import com.thoughtworks.xstream.security.WildcardTypePermission;
+import com.thoughtworks.xstream.security.InputManipulationException;
/**
@@ -1398,8 +1399,11 @@ public class XStream {
.println(
"Security framework of XStream not explicitly initialized, using predefined black list on your own risk.");
}
- return marshallingStrategy.unmarshal(root, reader, dataHolder, converterLookup, mapper);
-
+ try {
+ return marshallingStrategy.unmarshal(root, reader, dataHolder, converterLookup, mapper);
+ } catch (final StackOverflowError e) {
+ throw new InputManipulationException("Possible Denial of Service attack by Stack Overflow");
+ }
} catch (ConversionException e) {
Package pkg = getClass().getPackage();
String version = pkg != null ? pkg.getImplementationVersion() : null;
diff --git a/xstream/src/java/com/thoughtworks/xstream/security/AbstractSecurityException.java b/xstream/src/java/com/thoughtworks/xstream/security/AbstractSecurityException.java
new file mode 100644
index 0000000..777765a
--- /dev/null
+++ b/xstream/src/java/com/thoughtworks/xstream/security/AbstractSecurityException.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2021, 2022 XStream Committers.
+ * All rights reserved.
+ *
+ * Created on 21. September 2021 by Joerg Schaible
+ */
+package com.thoughtworks.xstream.security;
+
+import com.thoughtworks.xstream.XStreamException;
+
+
+/**
+ * General base class for a Security Exception in XStream.
+ *
+ * @author Jörg Schaible
+ * @since 1.4.19
+ */
+public abstract class AbstractSecurityException extends XStreamException {
+ private static final long serialVersionUID = 20210921L;
+
+ /**
+ * Constructs a SecurityException.
+ * @param message the exception message
+ * @since 1.4.19
+ */
+ public AbstractSecurityException(final String message) {
+ super(message);
+ }
+}
diff --git a/xstream/src/java/com/thoughtworks/xstream/security/InputManipulationException.java b/xstream/src/java/com/thoughtworks/xstream/security/InputManipulationException.java
new file mode 100644
index 0000000..80f492c
--- /dev/null
+++ b/xstream/src/java/com/thoughtworks/xstream/security/InputManipulationException.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2021, 2022 XStream Committers.
+ * All rights reserved.
+ *
+ * Created on 21. September 2021 by Joerg Schaible
+ */
+package com.thoughtworks.xstream.security;
+
+
+/**
+ * Class for a Security Exception assuming input manipulation in XStream.
+ *
+ * @author Jörg Schaible
+ * @since 1.4.19
+ */
+public class InputManipulationException extends AbstractSecurityException {
+ private static final long serialVersionUID = 20210921L;
+
+ /**
+ * Constructs a SecurityException.
+ * @param message the exception message
+ * @since 1.4.19
+ */
+ public InputManipulationException(final String message) {
+ super(message);
+ }
+}
diff --git a/xstream/src/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java b/xstream/src/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java
index d387bcd..f21ea45 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, 2020, 2021 XStream Committers.
+ * Copyright (C) 2013, 2014, 2017, 2018, 2020, 2021, 2022 XStream Committers.
* All rights reserved.
*
* The software in this package is published under the terms of the BSD
@@ -25,6 +25,8 @@ 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;
+import com.thoughtworks.xstream.security.InputManipulationException;
+
/**
@@ -187,4 +189,35 @@ public class SecurityVulnerabilityTest extends AbstractAcceptanceTest {
assertEquals("Unlimited reads of ByteArrayInputStream returning 0 bytes expected", 0, i);
}
}
+
+ public void testStackOverflowWithRecursiveHashSet() {
+ final String xml = ""
+ + "<set>\n"
+ + " <set>\n"
+ + " <set>\n"
+ + " <set>\n"
+ + " <set>\n"
+ + " <set>\n"
+ + " <string>a</string>\n"
+ + " </set>\n"
+ + " <set>\n"
+ + " <string>b</string>\n"
+ + " </set>\n"
+ + " </set>\n"
+ + " <set>\n"
+ + " <string>c</string>\n"
+ + " <set reference=\"../../../set/set[2]\"/>\n"
+ + " </set>\n"
+ + " </set>\n"
+ + " </set>\n"
+ + " </set>\n"
+ + "</set>";
+
+ try {
+ xstream.fromXML(xml);
+ fail("Thrown " + InputManipulationException.class.getName() + " expected");
+ } catch (final InputManipulationException e) {
+ assertTrue(e.getMessage().indexOf("Stack Overflow") >= 0);
+ }
+ }
}
|