Bug#909526: stretch-pu: package dom4j/1.6.1+dfsg.3-2
Package: release.debian.org
Severity: normal
Tags: stretch
User: release.debian.org@packages.debian.org
Usertags: pu
Dear release team,
I would like to update dom4j in Stretch. It is currently affected by
CVE-2018-1000632, a XML injection attack. The security team marked
this issue as no-dsa. Please find attached the debdiff.
Regards,
Markus
diff -Nru dom4j-1.6.1+dfsg.3/debian/changelog dom4j-1.6.1+dfsg.3/debian/changelog
--- dom4j-1.6.1+dfsg.3/debian/changelog 2013-06-26 23:31:01.000000000 +0200
+++ dom4j-1.6.1+dfsg.3/debian/changelog 2018-09-24 15:03:22.000000000 +0200
@@ -1,3 +1,18 @@
+dom4j (1.6.1+dfsg.3-2+deb9u1) stretch; urgency=high
+
+ * Team upload.
+ * Fix CVE-2018-1000632:
+ Mario Areias discovered that dom4j, a XML framework for Java, was
+ vulnerable to a XML injection attack. An attacker able to specify
+ attributes or elements in the XML document might be able to modify the
+ whole XML document.
+ * Compile with source/target 1.5 to fix a compilation issue with
+ String.format.
+ * Add testng to Build-Depends. Build and test AllowedCharsTest to verify that
+ CVE-2018-1000632 is correctly addressed.
+
+ -- Markus Koschany <apo@debian.org> Mon, 24 Sep 2018 15:03:22 +0200
+
dom4j (1.6.1+dfsg.3-2) unstable; urgency=low
* Removed the dependency on libjaxme-java
diff -Nru dom4j-1.6.1+dfsg.3/debian/control dom4j-1.6.1+dfsg.3/debian/control
--- dom4j-1.6.1+dfsg.3/debian/control 2013-06-26 23:12:47.000000000 +0200
+++ dom4j-1.6.1+dfsg.3/debian/control 2018-09-24 15:03:22.000000000 +0200
@@ -5,7 +5,7 @@
Uploaders: Marcus Better <marcus@better.se>, Emmanuel Bourg <ebourg@apache.org>
Build-Depends: debhelper (>= 7), ant-optional, default-jdk, maven-repo-helper, cdbs
Build-Depends-Indep: antlr, libjaxen-java, libxpp2-java, libxpp3-java,
- libxerces2-java, libxalan2-java (>= 2.7.0), junit, libjunitperf-java, libmsv-java,
+ libxerces2-java, libxalan2-java (>= 2.7.0), junit, testng, libjunitperf-java, libmsv-java,
librelaxng-datatype-java
Standards-Version: 3.9.4
Vcs-Svn: svn://anonscm.debian.org/pkg-java/trunk/dom4j
diff -Nru dom4j-1.6.1+dfsg.3/debian/patches/01_build-tweaks.patch dom4j-1.6.1+dfsg.3/debian/patches/01_build-tweaks.patch
--- dom4j-1.6.1+dfsg.3/debian/patches/01_build-tweaks.patch 2013-06-26 21:35:23.000000000 +0200
+++ dom4j-1.6.1+dfsg.3/debian/patches/01_build-tweaks.patch 2018-09-24 15:03:22.000000000 +0200
@@ -1,17 +1,26 @@
-Description:
- Link the Javadoc with the Java API installed with default-jre
- Fix the classpath for the tests
- Ignore test failures
+From: Debian Java Maintainers <pkg-java-maintainers@lists.alioth.debian.org>
+Date: Mon, 24 Sep 2018 15:45:49 +0200
+Subject: Link the Javadoc with the Java API installed with default-jre
+
+Fix the classpath for the tests
+Ignore test failures
Forwarded: not-needed
+---
+ build.xml | 17 ++++++++++++++---
+ 1 file changed, 14 insertions(+), 3 deletions(-)
+
+diff --git a/build.xml b/build.xml
+index 0f87f2d..215c727 100644
--- a/build.xml
+++ b/build.xml
-@@ -24,6 +24,15 @@
+@@ -24,6 +24,16 @@
<include name="xalan*.jar" />
<include name="xerces*.jar" />
</fileset>
+ <fileset dir="/usr/share/java">
+ <include name="jaxen.jar" />
+ <include name="junitperf.jar" />
++ <include name="testng.jar" />
+ <include name="relaxngDatatype.jar" />
+ <include name="xalan2.jar" />
+ <include name="xercesImpl.jar" />
@@ -21,7 +30,7 @@
</path>
<path id="samples.classpath">
-@@ -155,6 +164,7 @@
+@@ -155,6 +165,7 @@
<target name="compile-test" depends="compile">
<javac srcdir="${test.dir}"
destdir="${build.dest}"
@@ -29,7 +38,7 @@
debug="${debug}"
optimize="${optimize}"
deprecation="${deprecation}"
-@@ -219,7 +229,7 @@
+@@ -219,7 +230,7 @@
doctitle="${Name}"
bottom="Copyright © ${year} MetaStuff Ltd. All Rights Reserved. Hosted by <p> <img src='http://sourceforge.net/sflogo.php?group_id=16035' width='88' height='31' border='0' alt='SourceForge Logo' />"
stylesheetfile="${doc.dir}/style/javadoc.css">
@@ -38,7 +47,7 @@
<link href="http://java.sun.com/xml/jaxp-docs-1.1/docs/api"/>
</javadoc>
-@@ -236,7 +246,7 @@
+@@ -236,7 +247,7 @@
doctitle="${Name}"
bottom="Copyright © ${year} MetaStuff Ltd. All Rights Reserved. Hosted by <p> <img src='http://sourceforge.net/sflogo.php?group_id=16035' width='88' height='31' border='0' alt='SourceForge Logo' />"
stylesheetfile="${doc.dir}/style/javadoc.css">
@@ -47,7 +56,7 @@
<link href="http://java.sun.com/xml/jaxp-docs-1.1/docs/api"/>
<link href="${build.javadocs}"/>
</javadoc>
-@@ -270,7 +280,7 @@
+@@ -270,7 +281,7 @@
<!-- =================================================================== -->
<target name="test" depends="compile-test">
<mkdir dir="${build.dir}/test-results/xml"/>
diff -Nru dom4j-1.6.1+dfsg.3/debian/patches/CVE-2018-1000632.patch dom4j-1.6.1+dfsg.3/debian/patches/CVE-2018-1000632.patch
--- dom4j-1.6.1+dfsg.3/debian/patches/CVE-2018-1000632.patch 1970-01-01 01:00:00.000000000 +0100
+++ dom4j-1.6.1+dfsg.3/debian/patches/CVE-2018-1000632.patch 2018-09-24 15:03:22.000000000 +0200
@@ -0,0 +1,302 @@
+From: Markus Koschany <apo@debian.org>
+Date: Mon, 24 Sep 2018 14:53:44 +0200
+Subject: CVE-2018-1000632
+
+Bug-Upstream: https://github.com/dom4j/dom4j/issues/48
+Origin: https://github.com/dom4j/dom4j/commit/e598eb43d418744c4dbf62f647dd2381c9ce9387
+---
+ build.xml | 4 +-
+ src/java/org/dom4j/Namespace.java | 5 +-
+ src/java/org/dom4j/QName.java | 103 ++++++++++++++++++++++++++++++-
+ src/java/org/dom4j/tree/QNameCache.java | 4 +-
+ src/test/org/dom4j/AllowedCharsTest.java | 78 +++++++++++++++++++++++
+ 5 files changed, 189 insertions(+), 5 deletions(-)
+ create mode 100644 src/test/org/dom4j/AllowedCharsTest.java
+
+diff --git a/build.xml b/build.xml
+index 215c727..1bf154d 100644
+--- a/build.xml
++++ b/build.xml
+@@ -152,8 +152,8 @@
+ destdir="${build.dest}"
+ debug="${debug}"
+ optimize="${optimize}"
+- target="1.3"
+- source="1.3"
++ target="1.5"
++ source="1.5"
+ deprecation="${deprecation}"
+ classpathref="compile.classpath">
+ </javac>
+diff --git a/src/java/org/dom4j/Namespace.java b/src/java/org/dom4j/Namespace.java
+index 6be8ea3..55291a8 100644
+--- a/src/java/org/dom4j/Namespace.java
++++ b/src/java/org/dom4j/Namespace.java
+@@ -51,8 +51,11 @@ public class Namespace extends AbstractNode {
+ public Namespace(String prefix, String uri) {
+ this.prefix = (prefix != null) ? prefix : "";
+ this.uri = (uri != null) ? uri : "";
+- }
+
++ if (!this.prefix.isEmpty()) {
++ QName.validateNCName(this.prefix);
++ }
++ }
+ /**
+ * A helper method to return the Namespace instance for the given prefix and
+ * URI
+diff --git a/src/java/org/dom4j/QName.java b/src/java/org/dom4j/QName.java
+index 2d706d4..9c8797a 100644
+--- a/src/java/org/dom4j/QName.java
++++ b/src/java/org/dom4j/QName.java
+@@ -11,6 +11,7 @@ import java.io.IOException;
+ import java.io.ObjectInputStream;
+ import java.io.ObjectOutputStream;
+ import java.io.Serializable;
++import java.util.regex.Pattern;
+
+ import org.dom4j.tree.QNameCache;
+ import org.dom4j.util.SingletonStrategy;
+@@ -23,11 +24,86 @@ import org.dom4j.util.SingletonStrategy;
+ * </p>
+ *
+ * @author <a href="mailto:jstrachan@apache.org">James Strachan </a>
++ * @author Filip Jirsák
+ */
+ public class QName implements Serializable {
+ /** The Singleton instance */
+ private static SingletonStrategy singleton = null;
+
++ /**
++ * {@code NameStartChar} without colon.
++ *
++ * <pre>NameStartChar ::= ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]</pre>
++ *
++ * @see <a href="https://www.w3.org/TR/xml/#sec-common-syn">XML 1.0 – 2.3 Common Syntactic Constructs</a>
++ * @see <a href="https://www.w3.org/TR/2006/REC-xml11-20060816/#sec-common-syn">XML 1.1 – 2.3 Common Syntactic Constructs</a>
++ */
++ private static final String NAME_START_CHAR = "_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD";
++
++ /**
++ * {@code NameChar} without colon.
++ *
++ * <pre>NameChar ::= NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]</pre>
++ *
++ * @see <a href="https://www.w3.org/TR/xml/#sec-common-syn">XML 1.0 – 2.3 Common Syntactic Constructs</a>
++ * @see <a href="https://www.w3.org/TR/2006/REC-xml11-20060816/#sec-common-syn">XML 1.1 – 2.3 Common Syntactic Constructs</a>
++ */
++ private static final String NAME_CHAR = NAME_START_CHAR + "-.0-9\u00B7\u0300-\u036F\u203F-\u2040";
++
++ /**
++ * {@code NCName}
++ *
++ * <pre>
++ * NCName ::= NCNameStartChar NCNameChar* (An XML Name, minus the ":")
++ * NCNameChar ::= NameChar -':'
++ * NCNameStartChar ::= NameStartChar -':'
++ * </pre>
++ *
++ * @see <a href="https://www.w3.org/TR/xml-names/#ns-qualnames">Namespaces in XML 1.0 – 4 Qualified Names</a>
++ * @see <a href="https://www.w3.org/TR/2006/REC-xml-names11-20060816/#ns-qualnames">Namespaces in XML 1.1 – 4 Qualified Names</a>
++ */
++ private static final String NCNAME = "["+NAME_START_CHAR+"]["+NAME_CHAR+"]*";
++
++ /**
++ * Regular expression for {@code Name} (with colon).
++ *
++ * <pre>Name ::= NameStartChar (NameChar)*</pre>
++ *
++ * @see <a href="https://www.w3.org/TR/xml/#sec-common-syn">XML 1.0 – 2.3 Common Syntactic Constructs</a>
++ * @see <a href="https://www.w3.org/TR/2006/REC-xml11-20060816/#sec-common-syn">XML 1.1 – 2.3 Common Syntactic Constructs</a>
++ */
++ private static final Pattern RE_NAME = Pattern.compile("[:"+NAME_START_CHAR+"][:"+NAME_CHAR+"]*");
++
++ /**
++ * Regular expression for {@code NCName}.
++ *
++ * <pre>
++ * NCName ::= NCNameStartChar NCNameChar* (An XML Name, minus the ":")
++ * NCNameChar ::= NameChar -':'
++ * NCNameStartChar ::= NameStartChar -':'
++ * </pre>
++ *
++ * @see <a href="https://www.w3.org/TR/xml-names/#ns-qualnames">Namespaces in XML 1.0 – 4 Qualified Names</a>
++ * @see <a href="https://www.w3.org/TR/2006/REC-xml-names11-20060816/#ns-qualnames">Namespaces in XML 1.1 – 4 Qualified Names</a>
++ */
++ private static final Pattern RE_NCNAME = Pattern.compile(NCNAME);
++
++ /**
++ * Regular expression for {@code QName}.
++ *
++ * <pre>
++ * QName ::= PrefixedName | UnprefixedName
++ * PrefixedName ::= Prefix ':' LocalPart
++ * UnprefixedName ::= LocalPart
++ * Prefix ::= NCName
++ * LocalPart ::= NCName
++ * </pre>
++ *
++ * @see <a href="https://www.w3.org/TR/xml-names/#ns-qualnames">Namespaces in XML 1.0 – 4 Qualified Names</a>
++ * @see <a href="https://www.w3.org/TR/2006/REC-xml-names11-20060816/#ns-qualnames">Namespaces in XML 1.1 – 4 Qualified Names</a>
++ */
++ private static final Pattern RE_QNAME = Pattern.compile("(?:"+NCNAME+":)?"+NCNAME);
++
+ static {
+ try {
+ String defaultSingletonClass = "org.dom4j.util.SimpleSingleton";
+@@ -73,6 +149,11 @@ public class QName implements Serializable {
+ this.name = (name == null) ? "" : name;
+ this.namespace = (namespace == null) ? Namespace.NO_NAMESPACE
+ : namespace;
++ if (this.namespace.equals(Namespace.NO_NAMESPACE)) {
++ validateName(this.name);
++ } else {
++ validateNCName(this.name);
++ }
+ }
+
+ public QName(String name, Namespace namespace, String qualifiedName) {
+@@ -80,12 +161,32 @@ public class QName implements Serializable {
+ this.qualifiedName = qualifiedName;
+ this.namespace = (namespace == null) ? Namespace.NO_NAMESPACE
+ : namespace;
++ validateNCName(this.name);
++ validateQName(this.qualifiedName);
+ }
+
+ public static QName get(String name) {
+ return getCache().get(name);
+ }
+
++ private static void validateName(String name) {
++ if (!RE_NAME.matcher(name).matches()) {
++ throw new IllegalArgumentException(String.format("Illegal character in name: '%s'.", name));
++ }
++ }
++
++ protected static void validateNCName(String ncname) {
++ if (!RE_NCNAME.matcher(ncname).matches()) {
++ throw new IllegalArgumentException(String.format("Illegal character in local name: '%s'.", ncname));
++ }
++ }
++
++ private static void validateQName(String qname) {
++ if (!RE_QNAME.matcher(qname).matches()) {
++ throw new IllegalArgumentException(String.format("Illegal character in qualified name: '%s'.", qname));
++ }
++ }
++
+ public static QName get(String name, Namespace namespace) {
+ return getCache().get(name, namespace);
+ }
+@@ -292,4 +393,4 @@ public class QName implements Serializable {
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
+- */
+\ No newline at end of file
++ */
+diff --git a/src/java/org/dom4j/tree/QNameCache.java b/src/java/org/dom4j/tree/QNameCache.java
+index e026424..11981b5 100644
+--- a/src/java/org/dom4j/tree/QNameCache.java
++++ b/src/java/org/dom4j/tree/QNameCache.java
+@@ -164,6 +164,8 @@ public class QNameCache {
+
+ if (index < 0) {
+ return get(qualifiedName, Namespace.get(uri));
++ } else if (index == 0){
++ throw new IllegalArgumentException("Qualified name cannot start with ':'.");
+ } else {
+ String name = qualifiedName.substring(index + 1);
+ String prefix = qualifiedName.substring(0, index);
+@@ -307,4 +309,4 @@ public class QNameCache {
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
+- */
+\ No newline at end of file
++ */
+diff --git a/src/test/org/dom4j/AllowedCharsTest.java b/src/test/org/dom4j/AllowedCharsTest.java
+new file mode 100644
+index 0000000..20c1de0
+--- /dev/null
++++ b/src/test/org/dom4j/AllowedCharsTest.java
+@@ -0,0 +1,78 @@
++package org.dom4j;
++
++import org.testng.annotations.Test;
++
++/**
++ * @author Filip Jirsák
++ */
++public class AllowedCharsTest {
++ @Test
++ public void localName() {
++ QName.get("element");
++ QName.get(":element");
++ QName.get("elem:ent");
++ }
++
++ @Test(expectedExceptions = IllegalArgumentException.class)
++ public void localNameFail() {
++ QName.get("!element");
++ }
++
++ @Test
++ public void qname() {
++ QName.get("element", "http://example.com/namespace");
++ QName.get("ns:element", "http://example.com/namespace");
++ }
++
++ @Test(expectedExceptions = IllegalArgumentException.class)
++ public void qnameFail1() {
++ QName.get("ns:elem:ent", "http://example.com/namespace");
++ }
++
++ @Test(expectedExceptions = IllegalArgumentException.class)
++ public void qnameFail2() {
++ QName.get(":nselement", "http://example.com/namespace");
++ }
++
++ @Test(expectedExceptions = IllegalArgumentException.class)
++ public void createElementLT() {
++ DocumentHelper.createElement("element<name");
++ }
++
++ @Test(expectedExceptions = IllegalArgumentException.class)
++ public void createElementGT() {
++ DocumentHelper.createElement("element>name");
++ }
++
++ @Test(expectedExceptions = IllegalArgumentException.class)
++ public void createElementAmpersand() {
++ DocumentHelper.createElement("element&name");
++ }
++
++ @Test(expectedExceptions = IllegalArgumentException.class)
++ public void addElement() {
++ Element root = DocumentHelper.createElement("root");
++ root.addElement("element>name");
++ }
++
++ @Test(expectedExceptions = IllegalArgumentException.class)
++ public void addElementQualified() {
++ Element root = DocumentHelper.createElement("root");
++ root.addElement("element>name", "http://example.com/namespace");
++ }
++
++ @Test(expectedExceptions = IllegalArgumentException.class)
++ public void addElementQualifiedPrefix() {
++ Element root = DocumentHelper.createElement("root");
++ root.addElement("ns:element>name", "http://example.com/namespace");
++ }
++
++ @Test(expectedExceptions = IllegalArgumentException.class)
++ public void addElementPrefix() {
++ Element root = DocumentHelper.createElement("root");
++ root.addElement("ns>:element", "http://example.com/namespace");
++ }
++
++ //TODO It is illegal to create element or attribute with namespace prefix and empty namespace IRI.
++ //See https://www.w3.org/TR/2006/REC-xml-names11-20060816/#scoping
++}
diff -Nru dom4j-1.6.1+dfsg.3/debian/patches/series dom4j-1.6.1+dfsg.3/debian/patches/series
--- dom4j-1.6.1+dfsg.3/debian/patches/series 2013-06-26 21:35:23.000000000 +0200
+++ dom4j-1.6.1+dfsg.3/debian/patches/series 2018-09-24 15:03:22.000000000 +0200
@@ -4,3 +4,5 @@
04_headless-test.patch
05_java7-compat.patch
06_dom-level3-support.patch
+CVE-2018-1000632.patch
+testng.patch
diff -Nru dom4j-1.6.1+dfsg.3/debian/patches/testng.patch dom4j-1.6.1+dfsg.3/debian/patches/testng.patch
--- dom4j-1.6.1+dfsg.3/debian/patches/testng.patch 1970-01-01 01:00:00.000000000 +0100
+++ dom4j-1.6.1+dfsg.3/debian/patches/testng.patch 2018-09-24 15:03:22.000000000 +0200
@@ -0,0 +1,43 @@
+From: Markus Koschany <apo@debian.org>
+Date: Mon, 24 Sep 2018 18:25:32 +0200
+Subject: testng
+
+Add a testng target to build.xml
+---
+ build.xml | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/build.xml b/build.xml
+index 61e9717..0c3b52b 100644
+--- a/build.xml
++++ b/build.xml
+@@ -28,6 +28,7 @@
+ <include name="jaxen.jar" />
+ <include name="junitperf.jar" />
+ <include name="testng.jar" />
++ <include name="jcommander.jar" />
+ <include name="relaxngDatatype.jar" />
+ <include name="xalan2.jar" />
+ <include name="xercesImpl.jar" />
+@@ -298,6 +299,21 @@
+ </junit>
+ </target>
+
++ <taskdef name="testng" classname="org.testng.TestNGAntTask">
++ <classpath location="/usr/share/java/testng.jar" />
++ </taskdef>
++
++<target name="testng" depends="compile">
++
++ <testng classpathref="test.classpath"
++ outputDir="${build.dir}/test-results/testng"
++ haltOnFailure="true">
++ <classpath location="${build.dest}" />
++ <classfileset dir="${build.dest}" includes="**/*AllowedCharsTest*.class" />
++ </testng>
++</target>
++
++
+ <target name="test-report" depends="test">
+ <mkdir dir="${build.dir}/test-results"/>
+ <junitreport todir="${build.dir}/test-results">
diff -Nru dom4j-1.6.1+dfsg.3/debian/rules dom4j-1.6.1+dfsg.3/debian/rules
--- dom4j-1.6.1+dfsg.3/debian/rules 2013-06-26 23:29:09.000000000 +0200
+++ dom4j-1.6.1+dfsg.3/debian/rules 2018-09-24 15:03:22.000000000 +0200
@@ -8,7 +8,7 @@
xalan2 xercesImpl ant-junit junit junitperf xsdlib
DEB_ANT_BUILD_TARGET := package release-javadoc
-DEB_ANT_CHECK_TARGET := test
+DEB_ANT_CHECK_TARGET := test testng
DEB_DH_INSTALLCHANGELOGS_ARGS := -k
DEB_INSTALL_CHANGELOGS_ALL := docs/changes-report.html
Reply to: