You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2017/09/18 12:57:38 UTC
svn commit: r1808695 - in /tomcat/trunk: java/org/apache/coyote/http11/
test/org/apache/coyote/http11/ webapps/docs/ webapps/docs/config/
Author: markt
Date: Mon Sep 18 12:57:38 2017
New Revision: 1808695
URL: http://svn.apache.org/viewvc?rev=1808695&view=rev
Log:
Add an option to control how to respond to requests with invalid HTTP header names
Modified:
tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java
tomcat/trunk/java/org/apache/coyote/http11/Http11InputBuffer.java
tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java
tomcat/trunk/test/org/apache/coyote/http11/TestHttp11InputBuffer.java
tomcat/trunk/webapps/docs/changelog.xml
tomcat/trunk/webapps/docs/config/http.xml
Modified: tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java?rev=1808695&r1=1808694&r2=1808695&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java Mon Sep 18 12:57:38 2017
@@ -91,6 +91,30 @@ public abstract class AbstractHttp11Prot
// ------------------------------------------------ HTTP specific properties
// ------------------------------------------ managed in the ProtocolHandler
+ private boolean rejectIllegalHeaderName = true;
+ /**
+ * If an HTTP request is received that contains an illegal header name (i.e.
+ * the header name is not a token) will the request be rejected (with a 400
+ * response) or will the illegal header be ignored.
+ *
+ * @return {@code true} if the request will be rejected or {@code false} if
+ * the header will be ignored
+ */
+ public boolean getRejectIllegalHeaderName() { return rejectIllegalHeaderName; }
+ /**
+ * If an HTTP request is received that contains an illegal header name (i.e.
+ * the header name is not a token) should the request be rejected (with a
+ * 400 response) or should the illegal header be ignored.
+ *
+ * @param rejectIllegalHeaderName {@code true} to reject requests with
+ * illegal header names, {@code false} to
+ * ignore the header
+ */
+ public void setRejectIllegalHeaderName(boolean rejectIllegalHeaderName) {
+ this.rejectIllegalHeaderName = rejectIllegalHeaderName;
+ }
+
+
private int maxSavePostSize = 4 * 1024;
/**
* Return the maximum size of the post which will be saved during FORM or
Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11InputBuffer.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11InputBuffer.java?rev=1808695&r1=1808694&r2=1808695&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/Http11InputBuffer.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http11/Http11InputBuffer.java Mon Sep 18 12:57:38 2017
@@ -64,6 +64,8 @@ public class Http11InputBuffer implement
private final MimeHeaders headers;
+ private final boolean rejectIllegalHeaderName;
+
/**
* State.
*/
@@ -146,12 +148,14 @@ public class Http11InputBuffer implement
// ----------------------------------------------------------- Constructors
- public Http11InputBuffer(Request request, int headerBufferSize) {
+ public Http11InputBuffer(Request request, int headerBufferSize,
+ boolean rejectIllegalHeaderName) {
this.request = request;
headers = request.getMimeHeaders();
this.headerBufferSize = headerBufferSize;
+ this.rejectIllegalHeaderName = rejectIllegalHeaderName;
filterLibrary = new InputFilter[0];
activeFilters = new InputFilter[0];
@@ -786,10 +790,11 @@ public class Http11InputBuffer implement
headerData.lastSignificantChar = pos;
break;
} else if (!HttpParser.isToken(chr)) {
- // If a non-token header is detected, skip the line and
- // ignore the header
+ // If a non-token characters are illegal in header names
+ // Parsing continues so the error can be reported in context
headerData.lastSignificantChar = pos;
byteBuffer.position(byteBuffer.position() - 1);
+ // skipLine() will handle the error
return skipLine();
}
@@ -921,11 +926,15 @@ public class Http11InputBuffer implement
headerData.lastSignificantChar = pos;
}
}
- if (log.isDebugEnabled()) {
- log.debug(sm.getString("iib.invalidheader",
+ if (rejectIllegalHeaderName || log.isDebugEnabled()) {
+ String message = sm.getString("iib.invalidheader",
new String(byteBuffer.array(), headerData.start,
headerData.lastSignificantChar - headerData.start + 1,
- StandardCharsets.ISO_8859_1)));
+ StandardCharsets.ISO_8859_1));
+ if (rejectIllegalHeaderName) {
+ throw new IllegalArgumentException(message);
+ }
+ log.debug(message);
}
headerParsePos = HeaderParsePosition.HEADER_START;
Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java?rev=1808695&r1=1808694&r2=1808695&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java Mon Sep 18 12:57:38 2017
@@ -156,7 +156,8 @@ public class Http11Processor extends Abs
userDataHelper = new UserDataHelper(log);
- inputBuffer = new Http11InputBuffer(request, protocol.getMaxHttpHeaderSize());
+ inputBuffer = new Http11InputBuffer(request, protocol.getMaxHttpHeaderSize(),
+ protocol.getRejectIllegalHeaderName());
request.setInputBuffer(inputBuffer);
outputBuffer = new Http11OutputBuffer(response, protocol.getMaxHttpHeaderSize());
Modified: tomcat/trunk/test/org/apache/coyote/http11/TestHttp11InputBuffer.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/coyote/http11/TestHttp11InputBuffer.java?rev=1808695&r1=1808694&r2=1808695&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/coyote/http11/TestHttp11InputBuffer.java (original)
+++ tomcat/trunk/test/org/apache/coyote/http11/TestHttp11InputBuffer.java Mon Sep 18 12:57:38 2017
@@ -33,6 +33,7 @@ import static org.junit.Assert.assertTru
import org.junit.Test;
import org.apache.catalina.Context;
+import org.apache.catalina.connector.Connector;
import org.apache.catalina.startup.SimpleHttpClient;
import org.apache.catalina.startup.TesterServlet;
import org.apache.catalina.startup.Tomcat;
@@ -130,6 +131,28 @@ public class TestHttp11InputBuffer exten
@Test
+ public void testBug51557Valid() {
+
+ Bug51557Client client = new Bug51557Client("X-Bug51557Valid", "1234");
+
+ client.doRequest();
+ assertTrue(client.isResponse200());
+ assertEquals("1234abcd", client.getResponseBody());
+ assertTrue(client.isResponseBodyOK());
+ }
+
+
+ @Test
+ public void testBug51557Invalid() {
+
+ Bug51557Client client = new Bug51557Client("X-Bug51557=Invalid", "1234", true);
+
+ client.doRequest();
+ assertTrue(client.isResponse400());
+ }
+
+
+ @Test
public void testBug51557NoColon() {
Bug51557Client client = new Bug51557Client("X-Bug51557NoColon");
@@ -220,17 +243,25 @@ public class TestHttp11InputBuffer exten
*/
private class Bug51557Client extends SimpleHttpClient {
- private String headerName;
- private String headerLine;
+ private final String headerName;
+ private final String headerLine;
+ private final boolean rejectIllegalHeaderName;
public Bug51557Client(String headerName) {
this.headerName = headerName;
this.headerLine = headerName;
+ this.rejectIllegalHeaderName = false;
}
public Bug51557Client(String headerName, String headerValue) {
+ this(headerName, headerValue, false);
+ }
+
+ public Bug51557Client(String headerName, String headerValue,
+ boolean rejectIllegalHeaderName) {
this.headerName = headerName;
this.headerLine = headerName + ": " + headerValue;
+ this.rejectIllegalHeaderName = rejectIllegalHeaderName;
}
private Exception doRequest() {
@@ -243,8 +274,12 @@ public class TestHttp11InputBuffer exten
root.addServletMappingDecoded("/test", "Bug51557");
try {
+ Connector connector = tomcat.getConnector();
+ connector.setProperty("rejectIllegalHeaderName",
+ Boolean.toString(rejectIllegalHeaderName));
tomcat.start();
- setPort(tomcat.getConnector().getLocalPort());
+ setPort(connector.getLocalPort());
+
// Open connection
connect();
@@ -511,8 +546,10 @@ public class TestHttp11InputBuffer exten
root.addServletMappingDecoded("/test", "Bug59089");
try {
+ Connector connector = tomcat.getConnector();
+ connector.setProperty("rejectIllegalHeaderName", "false");
tomcat.start();
- setPort(tomcat.getConnector().getLocalPort());
+ setPort(connector.getLocalPort());
// Open connection
connect();
Modified: tomcat/trunk/webapps/docs/changelog.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1808695&r1=1808694&r2=1808695&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Mon Sep 18 12:57:38 2017
@@ -52,6 +52,11 @@
configuration of a connector at runtime without having to restart the
Connector. (markt)
</add>
+ <add>
+ Add an option to reject requests that contain HTTP headers with invalid
+ (non-token) header names with a 400 response and reject such requests by
+ default. (markt)
+ </add>
</changelog>
</subsection>
</section>
Modified: tomcat/trunk/webapps/docs/config/http.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/http.xml?rev=1808695&r1=1808694&r2=1808695&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/config/http.xml (original)
+++ tomcat/trunk/webapps/docs/config/http.xml Mon Sep 18 12:57:38 2017
@@ -543,6 +543,14 @@
expected concurrent requests (synchronous and asynchronous).</p>
</attribute>
+ <attribute name="rejectIllegalHeaderName" required="false">
+ <p>If an HTTP request is received that contains an illegal header name
+ (i.e. the header name is not a token) this setting determines if the
+ request will be rejected with a 400 response (<code>true</code>) or if the
+ illegal header be ignored (<code>false</code>). The default value is
+ <code>true</code> which will cause the request to be rejected.</p>
+ </attribute>
+
<attribute name="restrictedUserAgents" required="false">
<p>The value is a regular expression (using <code>java.util.regex</code>)
matching the <code>user-agent</code> header of HTTP clients for which
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org