tomcat6: CVE-2014-0227: HTTP request smuggling or DoS by streaming malformed data
Source: tomcat6 Version: 6.0.35-6+deb7u1 Severity: important Tags: security patch upstream fixed-upstream Hi there, The following vulnerability affects current tomcat 6.x in squeeze and wheezy. According to CVE-2014-0227 [cve], "Apache Tomcat 6.x before 6.0.42, 7.x before 7.0.55, and 8.x before 8.0.9 does not properly handle attempts to continue reading data after an error has occurred, which allows remote attackers to conduct HTTP request smuggling attacks or cause a denial of service (resource consumption) by streaming data with malformed chunked transfer coding". I have prepared the attached patch, based on [fix]. If you fix the vulnerability please also make sure to include the CVE (Common Vulnerabilities & Exposures) id in your changelog entry. [cve] https://security-tracker.debian.org/tracker/CVE-2014-0227 [fix] https://svn.apache.org/viewvc?view=revision&revision=1603628 Please adjust the affected versions in the BTS as needed. Cheers, Santiago Description: Improvements to ChunkedInputFilter - Clean-up - i18n for ChunkedInputFilter error message - Add error flag to allow subsequent attempts at reading after an error to fail fast Fixes CVE-2014-0227 Origin: https://svn.apache.org/viewvc?view=revision&revision=1603628 Index: tomcat6-6.0.41/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java === --- tomcat6-6.0.41.orig/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java +++ tomcat6-6.0.41/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java @@ -14,7 +14,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.apache.coyote.http11.filters; import java.io.EOFException; @@ -29,6 +28,7 @@ import org.apache.coyote.http11.Constant import org.apache.coyote.http11.InputFilter; import org.apache.tomcat.util.buf.MessageBytes; import org.apache.tomcat.util.http.MimeHeaders; +import org.apache.tomcat.util.res.StringManager; /** * Chunked input filter. Parses chunked data according to @@ -39,9 +39,11 @@ import org.apache.tomcat.util.http.MimeH */ public class ChunkedInputFilter implements InputFilter { +private static final StringManager sm = StringManager.getManager( +ChunkedInputFilter.class.getPackage().getName()); -// -- Constants +// -- Constants protected static final String ENCODING_NAME = "chunked"; protected static final ByteChunk ENCODING = new ByteChunk(); @@ -49,7 +51,6 @@ public class ChunkedInputFilter implemen // - Static Initializer - static { ENCODING.setBytes(ENCODING_NAME.getBytes(), 0, ENCODING_NAME.length()); } @@ -57,7 +58,6 @@ public class ChunkedInputFilter implemen // - Instance Variables - /** * Next buffer in the pipeline. */ @@ -120,6 +120,11 @@ public class ChunkedInputFilter implemen /** + * Flag that indicates if an error has occurred. + */ +private boolean error; + +/** * Flag set to true if the next call to doRead() must parse a CRLF pair * before doing anything else. */ @@ -130,13 +135,10 @@ public class ChunkedInputFilter implemen * Request being parsed. */ private Request request; - -// - Properties // InputBuffer Methods - /** * Read bytes. * @@ -146,11 +148,12 @@ public class ChunkedInputFilter implemen * whichever is greater. If the filter does not do request body length * control, the returned value should be -1. */ -public int doRead(ByteChunk chunk, Request req) -throws IOException { - -if (endChunk) +public int doRead(ByteChunk chunk, Request req) throws IOException { +if (endChunk) { return -1; +} + +checkError(); if(needCRLFParse) { needCRLFParse = false; @@ -159,7 +162,7 @@ public class ChunkedInputFilter implemen if (remaining <= 0) { if (!parseChunkHeader()) { -throw new IOException("Invalid chunk header"); +throwIOException(sm.getString("chunkedInputFilter.invalidHeader")); } if (endChunk) { parseEndChunk(); @@ -171,8 +174,7 @@ public class ChunkedInputFilter implemen if (pos >= lastValid) { if (readBytes() < 0) { -throw new IOException( -"Unexpected end of stream whilst reading request body"); +throwIOException(sm.getString("chunkedInputFilter.eos"));
CVE-2014-0230: non-persistent DoS attack by feeding data aborting an upload
Source: tomcat6 Version: 6.0.41-2+squeeze6 Severity: normal Tags: security upstream fixed-upstream Hello, The following vulnerability affects tomcat6 in squeeze and wheezy. CVE-2014-0230 [cve]: Tomcat permits a limited Denial of Service. I have prepared the attached patch for the 6.0.41-2+squeeze6 version, based on [fix]. If you fix the vulnerability please also make sure to include the CVE (Common Vulnerabilities & Exposures) id in your changelog entry. [cve] https://security-tracker.debian.org/tracker/CVE-2014-0230 [fix] https://svn.apache.org/viewvc?view=revision&revision=1659537 Please adjust the affected versions in the BTS as needed. Regards, Santiago Description: Add support for maxSwallowSize Fixes CVE-2014-0230 Origin: https://svn.apache.org/viewvc?view=revision&revision=1659537 Index: tomcat6-6.0.41/java/org/apache/coyote/http11/filters/IdentityInputFilter.java === --- tomcat6-6.0.41.orig/java/org/apache/coyote/http11/filters/IdentityInputFilter.java +++ tomcat6-6.0.41/java/org/apache/coyote/http11/filters/IdentityInputFilter.java @@ -20,7 +20,7 @@ package org.apache.coyote.http11.filters import java.io.IOException; import org.apache.tomcat.util.buf.ByteChunk; - +import org.apache.tomcat.util.res.StringManager; import org.apache.coyote.InputBuffer; import org.apache.coyote.Request; import org.apache.coyote.http11.InputFilter; @@ -32,9 +32,11 @@ import org.apache.coyote.http11.InputFil */ public class IdentityInputFilter implements InputFilter { +private static final StringManager sm = StringManager.getManager( +IdentityInputFilter.class.getPackage().getName()); -// -- Constants +// -- Constants protected static final String ENCODING_NAME = "identity"; protected static final ByteChunk ENCODING = new ByteChunk(); @@ -150,17 +152,25 @@ public class IdentityInputFilter impleme } -/** - * End the current request. - */ -public long end() -throws IOException { +public long end() throws IOException { + +final int maxSwallowSize = org.apache.coyote.Constants.MAX_SWALLOW_SIZE; +final boolean maxSwallowSizeExceeded = (maxSwallowSize > -1 && remaining > maxSwallowSize); +long swallowed = 0; // Consume extra bytes. while (remaining > 0) { + int nread = buffer.doRead(endChunk, null); if (nread > 0 ) { +swallowed += nread; remaining = remaining - nread; +if (maxSwallowSizeExceeded && swallowed > maxSwallowSize) { +// Note: We do not fail early so the client has a chance to +// read the response before the connection is closed. See: +// http://httpd.apache.org/docs/2.0/misc/fin_wait_2.html#appendix +throw new IOException(sm.getString("inputFilter.maxSwallow")); +} } else { // errors are handled higher up. remaining = 0; } Index: tomcat6-6.0.41/java/org/apache/coyote/http11/filters/LocalStrings.properties === --- tomcat6-6.0.41.orig/java/org/apache/coyote/http11/filters/LocalStrings.properties +++ tomcat6-6.0.41/java/org/apache/coyote/http11/filters/LocalStrings.properties @@ -22,4 +22,6 @@ chunkedInputFilter.invalidCrlfNoCR=Inval chunkedInputFilter.invalidCrlfNoData=Invalid end of line sequence (no data available to read) chunkedInputFilter.invalidHeader=Invalid chunk header chunkedInputFilter.maxExtension=maxExtensionSize exceeded -chunkedInputFilter.maxTrailer=maxTrailerSize exceeded \ No newline at end of file +chunkedInputFilter.maxTrailer=maxTrailerSize exceeded + +inputFilter.maxSwallow=maxSwallowSize exceeded Index: tomcat6-6.0.41/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java === --- tomcat6-6.0.41.orig/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java +++ tomcat6-6.0.41/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java @@ -216,8 +216,15 @@ public class ChunkedInputFilter implemen * End the current request. */ public long end() throws IOException { +int maxSwallowSize = org.apache.coyote.Constants.MAX_SWALLOW_SIZE; +long swallowed = 0; +int read = 0; // Consume extra bytes : parse the stream until the end chunk is found -while (doRead(readChunk, null) >= 0) { +while ((read = doRead(readChunk, null)) >= 0) { +swallowed += read; +if (maxSwallowSize > -1 && swallowed > maxSwallowSize) { +throwIOException(sm.getString("inputFilter.maxSwallow")); +} } // Return the number of
Re: squeeze update of dnsmasq?
Hi Raphael. I'm over-committed trying to get the long-overdue 2.73 release of dnsmasq out at the moment, so if the LTS team could handle the Debian mechanics of this, that would really help me. I can confirm that the patch which fixes the issue is here http://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=blobdiff;f=src/rfc1035.c;h=a995ab50d74adde068c8839684f9b3a44f4976d0;hp=7a07b0cee90655e296f57fa79f4d4a3a409b7b89;hb=ad4a8ff7d9097008d7623df8543df435bfddeac8;hpb=04b0ac05377936d121a36873bb63d492cde292c9 The are three hunks in that patch, and hunks 1 and 3 apply to 2.55. (the version in squeeze) Hunk 2 is rejected by patch: this can be ignored, it simply removes a check which is now done more completely at the start of the function. I hope that helps. Cheers, Simon. On 13/05/15 14:07, Raphael Hertzog wrote: > Hello Simon, > > the Debian LTS team would like to fix the security issues which are > currently open in the Squeeze version of dnsmasq: > https://security-tracker.debian.org/tracker/CVE-2015-3294 > (but there are other lower severities issues also open see > https://security-tracker.debian.org/tracker/source-package/dnsmasq) > > Would you like to take care of this yourself? We are still understaffed so > any help is always highly appreciated. > > If yes, please follow the workflow we have defined here: > http://wiki.debian.org/LTS/Development > > If that workflow is a burden to you, feel free to just prepare an > updated source package and send it to debian-lts@lists.debian.org--- > a/src/rfc1035.c +++ b/src/rfc1035.c @@ -1198,7 +1198,10 @@ unsigned int extract_request(struct dns_header *header, size_t qlen, char *name, size_t setup_reply(struct dns_header *header, size_t qlen, struct all_addr *addrp, unsigned int flags, unsigned long ttl) { - unsigned char *p = skip_questions(header, qlen); + unsigned char *p; + + if (!(p = skip_questions(header, qlen))) +return 0; /* clear authoritative and truncated flags, set QR flag */ header->hb3 = (header->hb3 & ~(HB3_AA | HB3_TC)) | HB3_QR; @@ -1214,7 +1217,7 @@ size_t setup_reply(struct dns_header *header, size_t qlen, SET_RCODE(header, NOERROR); /* empty domain */ else if (flags == F_NXDOMAIN) SET_RCODE(header, NXDOMAIN); - else if (p && flags == F_IPV4) + else if (flags == F_IPV4) { /* we know the address */ SET_RCODE(header, NOERROR); header->ancount = htons(1); @@ -1222,7 +1225,7 @@ size_t setup_reply(struct dns_header *header, size_t qlen, add_resource_record(header, NULL, NULL, sizeof(struct dns_header), &p, ttl, NULL, T_A, C_IN, "4", addrp); } #ifdef HAVE_IPV6 - else if (p && flags == F_IPV6) + else if (flags == F_IPV6) { SET_RCODE(header, NOERROR); header->ancount = htons(1); > (via a debdiff, or with an URL pointing to the the source package, > or even with a pointer to your packaging repository), and the members > of the LTS team will take care of the rest. Indicate clearly whether you > have tested the updated package or not. > > If you don't want to take care of this update, it's not a problem, we > will do our best with your package. Just let us know whether you would > like to review and/or test the updated package before it gets released. > > Thank you very much. > > Raphaël Hertzog, > on behalf of the Debian LTS team. > > PS: A member of the LTS team might start working on this update at > any point in time. You can verify whether someone is registered > on this update in this file: > https://anonscm.debian.org/viewvc/secure-testing/data/dla-needed.txt?view=markup > -- To UNSUBSCRIBE, email to debian-lts-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org Archive: https://lists.debian.org/0c34.9070...@thekelleys.org.uk