[tomcat7] 01/02: Fix CVE-2013-4286: Information disclosure

Emmanuel Bourg ebourg-guest at moszumanska.debian.org
Fri Feb 28 22:39:55 UTC 2014


This is an automated email from the git hooks/post-receive script.

ebourg-guest pushed a commit to branch wheezy
in repository tomcat7.

commit 5062d34cb7dd367c0dc2dca95526ac7869661f1a
Author: Emmanuel Bourg <ebourg at apache.org>
Date:   Fri Feb 28 19:30:17 2014 +0100

    Fix CVE-2013-4286: Information disclosure
---
 debian/changelog                        |   2 +
 debian/patches/0023-CVE-2013-4286.patch | 127 ++++++++++++++++++++++++++++++++
 debian/patches/series                   |   1 +
 3 files changed, 130 insertions(+)

diff --git a/debian/changelog b/debian/changelog
index c7c8645..b3a3655 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -15,6 +15,8 @@ tomcat7 (7.0.28-4+deb7u1) wheezy-security; urgency=high
     transfer encoding, Tomcat ignored but did not limit any extensions that
     were included. This allows a client to perform a limited denial of service
     by streaming an unlimited amount of data to the server.
+  * Fix CVE-2013-4286: Reject requests with multiple content-length headers
+    or with a content-length header when chunked encoding is being used.
   * Replaced the expired certificates used by the tests
     (backported from Tomcat 7.0.39)
 
diff --git a/debian/patches/0023-CVE-2013-4286.patch b/debian/patches/0023-CVE-2013-4286.patch
new file mode 100644
index 0000000..4aa25ed
--- /dev/null
+++ b/debian/patches/0023-CVE-2013-4286.patch
@@ -0,0 +1,127 @@
+Description: Fix for CVE-2013-4286: Reject requests with multiple
+ content-length headers or with a content-length header when chunked
+ encoding is being used.
+Origin: backport from Tomcat 7.0.47, http://svn.apache.org/r1521854
+--- a/java/org/apache/coyote/ajp/AbstractAjpProcessor.java
++++ b/java/org/apache/coyote/ajp/AbstractAjpProcessor.java
+@@ -25,6 +25,8 @@
+ import java.security.cert.X509Certificate;
+ import java.util.concurrent.atomic.AtomicBoolean;
+ 
++import javax.servlet.http.HttpServletResponse;
++
+ import org.apache.coyote.AbstractProcessor;
+ import org.apache.coyote.ActionCode;
+ import org.apache.coyote.AsyncContextCallback;
+@@ -650,6 +652,7 @@
+         // Set this every time in case limit has been changed via JMX
+         headers.setLimit(endpoint.getMaxHeaderCount());
+ 
++        boolean contentLengthSet = false;
+         int hCount = requestHeaderMessage.getInt();
+         for(int i = 0 ; i < hCount ; i++) {
+             String hName = null;
+@@ -684,10 +687,16 @@
+ 
+             if (hId == Constants.SC_REQ_CONTENT_LENGTH ||
+                     (hId == -1 && tmpMB.equalsIgnoreCase("Content-Length"))) {
+-                // just read the content-length header, so set it
+                 long cl = vMB.getLong();
+-                if(cl < Integer.MAX_VALUE)
+-                    request.setContentLength( (int)cl );
++                if (contentLengthSet) {
++                    response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
++                    error = true;
++                } else {
++                    contentLengthSet = true;
++                    // Set the content-length header for the request
++                    if(cl < Integer.MAX_VALUE)
++                        request.setContentLength( (int)cl );
++                }
+             } else if (hId == Constants.SC_REQ_CONTENT_TYPE ||
+                     (hId == -1 && tmpMB.equalsIgnoreCase("Content-Type"))) {
+                 // just read the content-type header, so set it
+--- a/java/org/apache/coyote/http11/AbstractHttp11Processor.java
++++ b/java/org/apache/coyote/http11/AbstractHttp11Processor.java
+@@ -1242,10 +1242,20 @@
+ 
+         // Parse content-length header
+         long contentLength = request.getContentLengthLong();
+-        if (contentLength >= 0 && !contentDelimitation) {
+-            getInputBuffer().addActiveFilter
+-                (inputFilters[Constants.IDENTITY_FILTER]);
+-            contentDelimitation = true;
++        if (contentLength >= 0) {
++            if (contentDelimitation) {
++                // contentDelimitation being true at this point indicates that
++                // chunked encoding is being used but chunked encoding should
++                // not be used with a content length. RFC 2616, section 4.4,
++                // bullet 3 states Content-Length must be ignored in this case -
++                // so remove it.
++                headers.removeHeader("content-length");
++                request.setContentLength(-1);
++            } else {
++                getInputBuffer().addActiveFilter
++                        (inputFilters[Constants.IDENTITY_FILTER]);
++                contentDelimitation = true;
++            }
+         }
+ 
+         MessageBytes valueMB = headers.getValue("host");
+--- a/test/org/apache/coyote/http11/TestAbstractHttp11Processor.java
++++ b/test/org/apache/coyote/http11/TestAbstractHttp11Processor.java
+@@ -100,6 +100,54 @@
+ 
+ 
+     @Test
++    public void testWithTEChunked() throws Exception {
++        doTestWithTEChunked(false);
++    }
++
++
++    @Test
++    public void testWithTEChunkedWithCL() throws Exception {
++        // Should be ignored
++        doTestWithTEChunked(true);
++    }
++
++
++    private void doTestWithTEChunked(boolean withCL)
++            throws Exception {
++
++        Tomcat tomcat = getTomcatInstance();
++
++        // Use the normal Tomcat ROOT context
++        File root = new File("test/webapp-3.0");
++        tomcat.addWebapp("", root.getAbsolutePath());
++
++        tomcat.start();
++
++        String request =
++            "POST /echo-params.jsp HTTP/1.1" + SimpleHttpClient.CRLF +
++            "Host: any" + SimpleHttpClient.CRLF +
++            (withCL ? "Content-length: 1" + SimpleHttpClient.CRLF : "") +
++            "Transfer-encoding: chunked" + SimpleHttpClient.CRLF +
++            "Content-Type: application/x-www-form-urlencoded" +
++                    SimpleHttpClient.CRLF +
++            "Connection: close" + SimpleHttpClient.CRLF +
++            SimpleHttpClient.CRLF +
++            "9" + SimpleHttpClient.CRLF +
++            "test=data" + SimpleHttpClient.CRLF +
++            "0" + SimpleHttpClient.CRLF +
++            SimpleHttpClient.CRLF;
++
++        Client client = new Client(tomcat.getConnector().getLocalPort());
++        client.setRequest(new String[] {request});
++
++        client.connect();
++        client.processRequest();
++        assertTrue(client.isResponse200());
++        assertTrue(client.getResponseBody().contains("test - data"));
++    }
++
++
++    @Test
+     public void testWithTEIdentity() throws Exception {
+         Tomcat tomcat = getTomcatInstance();
+ 
diff --git a/debian/patches/series b/debian/patches/series
index 9c82f7c..8c41b6a 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -18,3 +18,4 @@ cve-2012-3439-tests.patch
 0020-CVE-2013-2071.patch
 0021-CVE-2012-3544.patch
 0022-update-test-certificates.patch
+0023-CVE-2013-4286.patch

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/tomcat7.git



More information about the pkg-java-commits mailing list