From: markt Date: Sun, 20 Dec 2009 17:21:06 +0000 (+0000) Subject: Better fix for https://issues.apache.org/bugzilla/show_bug.cgi?id=47963 X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=a4c1d4af9fa2eeea7198f445c725704ca96d4e92;p=tomcat7.0 Better fix for https://issues.apache.org/bugzilla/show_bug.cgi?id=47963 git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@892612 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/java/org/apache/coyote/ajp/AjpAprProcessor.java b/java/org/apache/coyote/ajp/AjpAprProcessor.java index 0a66f2399..5910ea936 100644 --- a/java/org/apache/coyote/ajp/AjpAprProcessor.java +++ b/java/org/apache/coyote/ajp/AjpAprProcessor.java @@ -954,13 +954,12 @@ public class AjpAprProcessor implements ActionHook { // HTTP header contents responseHeaderMessage.appendInt(response.getStatus()); String message = null; - if (org.apache.coyote.Constants.USE_CUSTOM_STATUS_MSG_IN_HEADER) { + if (org.apache.coyote.Constants.USE_CUSTOM_STATUS_MSG_IN_HEADER && + HttpMessages.isSafeInHttpHeader(response.getMessage())) { message = response.getMessage(); } if (message == null){ message = HttpMessages.getMessage(response.getStatus()); - } else { - message = message.replace('\n', ' ').replace('\r', ' '); } if (message == null) { // mod_jk + httpd 2.x fails with a null status message - bug 45026 diff --git a/java/org/apache/coyote/ajp/AjpProcessor.java b/java/org/apache/coyote/ajp/AjpProcessor.java index 05ee1b8f9..5b485469a 100644 --- a/java/org/apache/coyote/ajp/AjpProcessor.java +++ b/java/org/apache/coyote/ajp/AjpProcessor.java @@ -959,13 +959,12 @@ public class AjpProcessor implements ActionHook { // HTTP header contents responseHeaderMessage.appendInt(response.getStatus()); String message = null; - if (org.apache.coyote.Constants.USE_CUSTOM_STATUS_MSG_IN_HEADER) { + if (org.apache.coyote.Constants.USE_CUSTOM_STATUS_MSG_IN_HEADER && + HttpMessages.isSafeInHttpHeader(response.getMessage())) { message = response.getMessage(); } if (message == null){ message = HttpMessages.getMessage(response.getStatus()); - } else { - message = message.replace('\n', ' ').replace('\r', ' '); } if (message == null) { // mod_jk + httpd 2.x fails with a null status message - bug 45026 diff --git a/java/org/apache/coyote/http11/AbstractOutputBuffer.java b/java/org/apache/coyote/http11/AbstractOutputBuffer.java index 4a4716f72..34c2a1b7a 100644 --- a/java/org/apache/coyote/http11/AbstractOutputBuffer.java +++ b/java/org/apache/coyote/http11/AbstractOutputBuffer.java @@ -339,13 +339,14 @@ public abstract class AbstractOutputBuffer implements OutputBuffer{ // Write message String message = null; - if (org.apache.coyote.Constants.USE_CUSTOM_STATUS_MSG_IN_HEADER) { + if (org.apache.coyote.Constants.USE_CUSTOM_STATUS_MSG_IN_HEADER && + HttpMessages.isSafeInHttpHeader(response.getMessage())) { message = response.getMessage(); } if (message == null) { write(HttpMessages.getMessage(status)); } else { - write(message.replace('\n', ' ').replace('\r', ' ')); + write(message); } // End the response status line diff --git a/java/org/apache/coyote/http11/InternalAprOutputBuffer.java b/java/org/apache/coyote/http11/InternalAprOutputBuffer.java index 4d2c9b0b1..e34506f76 100644 --- a/java/org/apache/coyote/http11/InternalAprOutputBuffer.java +++ b/java/org/apache/coyote/http11/InternalAprOutputBuffer.java @@ -414,13 +414,14 @@ public class InternalAprOutputBuffer // Write message String message = null; - if (org.apache.coyote.Constants.USE_CUSTOM_STATUS_MSG_IN_HEADER) { + if (org.apache.coyote.Constants.USE_CUSTOM_STATUS_MSG_IN_HEADER && + HttpMessages.isSafeInHttpHeader(response.getMessage())) { message = response.getMessage(); } if (message == null) { write(HttpMessages.getMessage(status)); } else { - write(message.replace('\n', ' ').replace('\r', ' ')); + write(message); } // End the response status line diff --git a/java/org/apache/tomcat/util/http/HttpMessages.java b/java/org/apache/tomcat/util/http/HttpMessages.java index 1f05dc2e1..9e56679fa 100644 --- a/java/org/apache/tomcat/util/http/HttpMessages.java +++ b/java/org/apache/tomcat/util/http/HttpMessages.java @@ -104,4 +104,30 @@ public class HttpMessages { return (result.toString()); } + /** + * Is the provided message safe to use in an HTTP header. Safe messages must + * meet the requirements of RFC2616 - i.e. must consist only of TEXT. + * + * @param msg The message to test + * @return true if the message is safe to use in an HTTP + * header else false + */ + public static boolean isSafeInHttpHeader(String msg) { + // Nulls are fine. It is up to the calling code to address any NPE + // concerns + if (msg == null) { + return true; + } + + // TEXT is defined as OCTET excpet CTLs + // OCTET is defined as an 8-bit sequence of data + // CTL is defined as octets 0-31 and 127 + for (char c : msg.toCharArray()) { + if (c > 255 || c < 32 || c == 127) { + return false; + } + } + + return true; + } } diff --git a/java/org/apache/tomcat/util/http/res/LocalStrings.properties b/java/org/apache/tomcat/util/http/res/LocalStrings.properties index 457c46625..33102df97 100644 --- a/java/org/apache/tomcat/util/http/res/LocalStrings.properties +++ b/java/org/apache/tomcat/util/http/res/LocalStrings.properties @@ -13,7 +13,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -# HttpMessages +# HttpMessages. The values in this file will be used in HTTP headers and as such +# may only contain TEXT as defined by RFC 2616 sc.100=Continue sc.101=Switching Protocols sc.200=OK diff --git a/java/org/apache/tomcat/util/http/res/LocalStrings_es.properties b/java/org/apache/tomcat/util/http/res/LocalStrings_es.properties index a1bf2e175..d3f3837e5 100644 --- a/java/org/apache/tomcat/util/http/res/LocalStrings_es.properties +++ b/java/org/apache/tomcat/util/http/res/LocalStrings_es.properties @@ -13,7 +13,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -# HttpMessages +# HttpMessages. The values in this file will be used in HTTP headers and as such +# may only contain TEXT as defined by RFC 2616 sc.100=Continuar sc.101=Cambiando Protocolos sc.200=OK diff --git a/java/org/apache/tomcat/util/http/res/LocalStrings_fr.properties b/java/org/apache/tomcat/util/http/res/LocalStrings_fr.properties index 62a38b05d..79e57ca68 100644 --- a/java/org/apache/tomcat/util/http/res/LocalStrings_fr.properties +++ b/java/org/apache/tomcat/util/http/res/LocalStrings_fr.properties @@ -13,6 +13,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +# HttpMessages. The values in this file will be used in HTTP headers and as such +# may only contain TEXT as defined by RFC 2616 sc.100=Continuer sc.101=Changement de Protocols sc.200=OK diff --git a/java/org/apache/tomcat/util/http/res/LocalStrings_ja.properties b/java/org/apache/tomcat/util/http/res/LocalStrings_ja.properties new file mode 100644 index 000000000..99234bced --- /dev/null +++ b/java/org/apache/tomcat/util/http/res/LocalStrings_ja.properties @@ -0,0 +1,63 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# HttpMessages. The values in this file will be used in HTTP headers and as such +# may only contain TEXT as defined by RFC 2616. Since Japanese language messages +# do not meet this requirement, English text is used. +sc.100=Continue +sc.101=Switching Protocols +sc.200=OK +sc.201=Created +sc.202=Accepted +sc.203=Non-Authoritative Information +sc.204=No Content +sc.205=Reset Content +sc.206=Partial Content +sc.207=Multi-Status +sc.300=Multiple Choices +sc.301=Moved Permanently +sc.302=Moved Temporarily +sc.303=See Other +sc.304=Not Modified +sc.305=Use Proxy +sc.307=Temporary Redirect +sc.400=Bad Request +sc.401=Unauthorized +sc.402=Payment Required +sc.403=Forbidden +sc.404=Not Found +sc.405=Method Not Allowed +sc.406=Not Acceptable +sc.407=Proxy Authentication Required +sc.408=Request Timeout +sc.409=Conflict +sc.410=Gone +sc.411=Length Required +sc.412=Precondition Failed +sc.413=Request Entity Too Large +sc.414=Request-URI Too Long +sc.415=Unsupported Media Type +sc.416=Requested Range Not Satisfiable +sc.417=Expectation Failed +sc.422=Unprocessable Entity +sc.423=Locked +sc.424=Failed Dependency +sc.500=Internal Server Error +sc.501=Not Implemented +sc.502=Bad Gateway +sc.503=Service Unavailable +sc.504=Gateway Timeout +sc.505=HTTP Version Not Supported +sc.507=Insufficient Storage diff --git a/webapps/docs/config/systemprops.xml b/webapps/docs/config/systemprops.xml index 7a43ba025..53f88a465 100644 --- a/webapps/docs/config/systemprops.xml +++ b/webapps/docs/config/systemprops.xml @@ -203,9 +203,11 @@

If this is true custom HTTP status messages will be used within HTTP - headers. Users must ensure that any such message is ISO-8859-1 encoded, - particularly if user provided input is included in the message, to prevent - a possible XSS vulnerability. If not specified the default value of + headers. If a custom message is specified that is not valid for use in an + HTTP header (as defined by RFC2616) then the custom message will be + ignored and the default message used. Note that there is some overhead + associated with the additional checking that is performed when custom + messages are used. If not specified the default value of false will be used.