Index: conf/catalina.properties =================================================================== --- conf/catalina.properties (revision 1780600) +++ conf/catalina.properties (working copy) @@ -131,3 +131,6 @@ #tomcat.util.buf.StringCache.char.enabled=true #tomcat.util.buf.StringCache.trainThreshold=500000 #tomcat.util.buf.StringCache.cacheSize=5000 + +# Allow for changes to HTTP request validation +tomcat.util.http.parser.HttpParser.blacklist=" \"#<>\\^`{|}" Index: java/org/apache/tomcat/util/http/parser/HttpParser.java =================================================================== --- java/org/apache/tomcat/util/http/parser/HttpParser.java (revision 1780600) +++ java/org/apache/tomcat/util/http/parser/HttpParser.java (working copy) @@ -61,6 +61,7 @@ private static final boolean[] IS_HEX = new boolean[ARRAY_SIZE]; private static final boolean[] IS_NOT_REQUEST_TARGET = new boolean[ARRAY_SIZE]; private static final boolean[] IS_HTTP_PROTOCOL = new boolean[ARRAY_SIZE]; + private static final boolean[] IS_IN_BLACKLIST = new boolean[ARRAY_SIZE]; static { // Digest field types. @@ -82,6 +83,13 @@ // RFC2617 says nc is 8LHEX. <">8LHEX<"> will also be accepted fieldTypes.put("nc", FIELD_TYPE_LHEX); + String prop = System.getProperty("tomcat.util.http.parser.HttpParser.blacklist"); + if (prop != null) { + for (int i = 0; i < prop.length(); i++) { + IS_IN_BLACKLIST[prop.charAt(i)] = true; + } + } + for (int i = 0; i < ARRAY_SIZE; i++) { // Control> 0-31, 127 if (i < 32 || i == 127) { @@ -109,9 +117,7 @@ // Not valid for request target. // Combination of multiple rules from RFC7230 and RFC 3986. Must be // ASCII, no controls plus a few additional characters excluded - if (IS_CONTROL[i] || i > 127 || - i == ' ' || i == '\"' || i == '#' || i == '<' || i == '>' || i == '\\' || - i == '^' || i == '`' || i == '{' || i == '|' || i == '}') { + if (IS_CONTROL[i] || i > 127 || IS_IN_BLACKLIST[i]) { IS_NOT_REQUEST_TARGET[i] = true; }