You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by bc...@apache.org on 2018/02/28 17:00:39 UTC
[trafficserver] branch master updated: Return 400 if there is
whitespace after the field name and before the colon
This is an automated email from the ASF dual-hosted git repository.
bcall pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/master by this push:
new 08512de Return 400 if there is whitespace after the field name and before the colon
08512de is described below
commit 08512deb11a610ae7084ce678b19bd637e30b3e1
Author: Bryan Call <bc...@apache.org>
AuthorDate: Fri Feb 23 14:48:53 2018 -0800
Return 400 if there is whitespace after the field name and before the
colon
---
proxy/hdrs/HdrTest.cc | 2 +-
proxy/hdrs/MIME.cc | 11 ++++-
tests/gold_tests/headers/syntax.200.gold | 6 +++
tests/gold_tests/headers/syntax.400.gold | 4 ++
tests/gold_tests/headers/syntax.test.py | 84 ++++++++++++++++++++++++++++++++
5 files changed, 104 insertions(+), 3 deletions(-)
diff --git a/proxy/hdrs/HdrTest.cc b/proxy/hdrs/HdrTest.cc
index eaa98e7..c355b00 100644
--- a/proxy/hdrs/HdrTest.cc
+++ b/proxy/hdrs/HdrTest.cc
@@ -496,7 +496,7 @@ HdrTest::test_mime()
"continuation: part1\r\n"
" part2\r\n"
"scooby: doo\r\n"
- "scooby : doo\r\n"
+ " scooby: doo\r\n"
"bar: foo\r\n"
"\r\n",
};
diff --git a/proxy/hdrs/MIME.cc b/proxy/hdrs/MIME.cc
index 8dfc155..1d87e41 100644
--- a/proxy/hdrs/MIME.cc
+++ b/proxy/hdrs/MIME.cc
@@ -2619,8 +2619,15 @@ mime_parser_parse(MIMEParser *parser, HdrHeap *heap, MIMEHdrImpl *mh, const char
continue; // toss away garbage line
}
field_name_last = colon - 1;
- while ((field_name_last >= field_name_first) && is_ws(*field_name_last)) {
- --field_name_last;
+ // RFC7230 section 3.2.4:
+ // No whitespace is allowed between the header field-name and colon. In
+ // the past, differences in the handling of such whitespace have led to
+ // security vulnerabilities in request routing and response handling. A
+ // server MUST reject any received request message that contains
+ // whitespace between a header field-name and colon with a response code
+ // of 400 (Bad Request).
+ if ((field_name_last >= field_name_first) && is_ws(*field_name_last)) {
+ return PARSE_RESULT_ERROR;
}
// find value first
diff --git a/tests/gold_tests/headers/syntax.200.gold b/tests/gold_tests/headers/syntax.200.gold
new file mode 100644
index 0000000..3b224e6
--- /dev/null
+++ b/tests/gold_tests/headers/syntax.200.gold
@@ -0,0 +1,6 @@
+HTTP/1.1 200 OK
+Date: ``
+Age: 0
+Transfer-Encoding: chunked
+Connection: keep-alive
+Server: ``
diff --git a/tests/gold_tests/headers/syntax.400.gold b/tests/gold_tests/headers/syntax.400.gold
new file mode 100644
index 0000000..b2502a6
--- /dev/null
+++ b/tests/gold_tests/headers/syntax.400.gold
@@ -0,0 +1,4 @@
+HTTP/1.1 400 Invalid HTTP Request
+Date: ``
+Connection: keep-alive
+Server: ``
diff --git a/tests/gold_tests/headers/syntax.test.py b/tests/gold_tests/headers/syntax.test.py
new file mode 100644
index 0000000..e38b97e
--- /dev/null
+++ b/tests/gold_tests/headers/syntax.test.py
@@ -0,0 +1,84 @@
+'''
+Test whitespace between field name and colon in the header
+'''
+# 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.
+
+import os
+Test.Summary = '''
+Test whitespace between field name and colon in the header
+'''
+
+# Needs Curl
+Test.SkipUnless(
+ Condition.HasProgram("curl", "Curl need to be installed on system for this test to work")
+)
+Test.ContinueOnFail = True
+
+# Define default ATS
+ts = Test.MakeATSProcess("ts", select_ports=False)
+server = Test.MakeOriginServer("server")
+
+#**testname is required**
+testName = ""
+request_header = {"headers": "GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n", "timestamp": "1469733493.993", "body": ""}
+response_header = {"headers": "HTTP/1.1 200 OK\r\nConnection: close\r\n\r\n", "timestamp": "1469733493.993", "body": ""}
+server.addResponse("sessionlog.json", request_header, response_header)
+
+# ATS Configuration
+ts.addSSLfile("../remap/ssl/server.pem")
+ts.addSSLfile("../remap/ssl/server.key")
+
+ts.Variables.ssl_port = 4443
+ts.Disk.records_config.update({
+ 'proxy.config.diags.debug.enabled': 1,
+ 'proxy.config.diags.debug.tags': 'ssl',
+ 'proxy.config.ssl.server.cert.path': '{0}'.format(ts.Variables.SSLDir),
+ 'proxy.config.ssl.server.private_key.path': '{0}'.format(ts.Variables.SSLDir),
+ 'proxy.config.http.server_ports': '{0} {1}:ssl'.format(ts.Variables.port, ts.Variables.ssl_port),
+})
+
+ts.Disk.remap_config.AddLine(
+ 'map http://www.example.com http://127.0.0.1:{0}'.format(server.Variables.Port)
+)
+
+ts.Disk.ssl_multicert_config.AddLine(
+ 'dest_ip=* ssl_cert_name=server.pem ssl_key_name=server.key'
+)
+
+# Test 1 - 200 Response
+tr = Test.AddTestRun()
+tr.Processes.Default.StartBefore(server)
+tr.Processes.Default.StartBefore(Test.Processes.ts)
+tr.Processes.Default.StartBefore(Test.Processes.ts, ready=When.PortOpen(ts.Variables.ssl_port))
+tr.Processes.Default.Command = 'curl -s -D - -v --ipv4 --http1.1 -H " foo: bar" -H "Host: www.example.com" http://localhost:8080/'
+tr.Processes.Default.ReturnCode = 0
+tr.Processes.Default.Streams.stdout = "syntax.200.gold"
+tr.StillRunningAfter = ts
+
+# Test 2 - 400 Response
+tr = Test.AddTestRun()
+tr.Processes.Default.Command = 'curl -s -D - -v --ipv4 --http1.1 -H "foo : bar" -H "Host: www.example.com" http://localhost:8080/'
+tr.Processes.Default.ReturnCode = 0
+tr.Processes.Default.Streams.stdout = "syntax.400.gold"
+tr.StillRunningAfter = ts
+
+# Test 3 - 400 Response
+tr = Test.AddTestRun()
+tr.Processes.Default.Command = 'curl -s -D - -v --ipv4 --http1.1 -H "foo : bar" -H "Host: www.example.com" http://localhost:8080/'
+tr.Processes.Default.ReturnCode = 0
+tr.Processes.Default.Streams.stdout = "syntax.400.gold"
+tr.StillRunningAfter = ts
--
To stop receiving notification emails like this one, please contact
bcall@apache.org.