Version in base suite: 8.1.1+ds-1.1 Base version: trafficserver_8.1.1+ds-1.1 Target version: trafficserver_8.1.1+ds-1.1+deb11u1 Base file: /srv/ftp-master.debian.org/ftp/pool/main/t/trafficserver/trafficserver_8.1.1+ds-1.1.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/t/trafficserver/trafficserver_8.1.1+ds-1.1+deb11u1.dsc changelog | 12 patches/0019-CVE_2021_37147.patch | 49 +++ patches/0019-CVE_2021_37148.patch | 37 ++ patches/0019-CVE_2021_37149.patch | 235 +++++++++++++++++ patches/0019-CVE_2021_38161.patch | 30 ++ patches/0019-CVE_2021_44040.patch | 513 ++++++++++++++++++++++++++++++++++++++ patches/0019-CVE_2021_44759.patch | 79 +++++ patches/series | 6 8 files changed, 961 insertions(+) diff -Nru trafficserver-8.1.1+ds/debian/changelog trafficserver-8.1.1+ds/debian/changelog --- trafficserver-8.1.1+ds/debian/changelog 2021-07-15 19:48:17.000000000 +0000 +++ trafficserver-8.1.1+ds/debian/changelog 2022-05-21 17:28:31.000000000 +0000 @@ -1,3 +1,15 @@ +trafficserver (8.1.1+ds-1.1+deb11u1) bullseye-security; urgency=high + + * Multiple CVE fixes for 8.1.x + + CVE-2021-37147: Improper input validation vulnerability + + CVE-2021-37148: Improper input validation vulnerability + + CVE-2021-37149: Improper Input Validation vulnerability + + CVE-2021-38161: Improper Authentication vulnerability in TLS origin verification + + CVE-2021-44040: Improper Input Validation vulnerability in request line parsing + + CVE-2021-44759: Improper Authentication vulnerability in TLS origin validation + + -- Jean Baptiste Favre Sat, 21 May 2022 19:28:31 +0200 + trafficserver (8.1.1+ds-1.1) unstable; urgency=medium * Non-maintainer upload. diff -Nru trafficserver-8.1.1+ds/debian/patches/0019-CVE_2021_37147.patch trafficserver-8.1.1+ds/debian/patches/0019-CVE_2021_37147.patch --- trafficserver-8.1.1+ds/debian/patches/0019-CVE_2021_37147.patch 1970-01-01 00:00:00.000000000 +0000 +++ trafficserver-8.1.1+ds/debian/patches/0019-CVE_2021_37147.patch 2022-05-21 17:28:31.000000000 +0000 @@ -0,0 +1,49 @@ +Description: Fix output '\n' HTTP field line endings + This is another attempt to fix what was initially addressed in #8096 but + got backed out via #8305. That more extensive patch was considered too + invasive and potentially risky. This more targeted patch will fix + clients that only send the \n endings but it will force the \r\n line + ending on output. + This was mostly in place except for header lines that get + m_n_v_raw_printable set, which seems to be most header lines. The + addition checks to see if the header line ends in \r\n. If it does not + the m_n_v_raw_printable flag gets cleared and the logic that explicitly + adds the line endings while be invoked on output. +Author: Brian Neradt +Origin: upstream +Applied-Upstream: https://github.com/apache/trafficserver/commit/5cad961c87cb07fbb8fa6890685d9878a169378d +Reviewed-by: Jean Baptiste Favre +Last-Update: 2022-05-21 +--- +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ +Index: trafficserver/proxy/hdrs/MIME.cc +=================================================================== +--- trafficserver.orig/proxy/hdrs/MIME.cc 2022-05-21 19:01:36.000000000 +0200 ++++ trafficserver/proxy/hdrs/MIME.cc 2022-05-21 19:02:12.210230747 +0200 +@@ -2652,8 +2652,17 @@ + + // find_value_last + field_value_last = line_e - 1; ++ int suffix_count = 0; + while ((field_value_last >= field_value_first) && ParseRules::is_wslfcr(*field_value_last)) { + --field_value_last; ++ ++suffix_count; ++ } ++ ++ // Make sure the field ends in CRLF. If not, we'll fix the field via the n_v_raw_printable ++ // flag. ++ bool raw_print_field = true; ++ if (suffix_count < 2 || *(line_e - 2) != '\r' || *(line_e - 1) != '\n') { ++ raw_print_field = false; + } + + field_name_length = (int)(field_name_last - field_name_first + 1); +@@ -2690,7 +2699,7 @@ + + MIMEField *field = mime_field_create(heap, mh); + mime_field_name_value_set(heap, mh, field, field_name_wks_idx, field_name_first, field_name_length, field_value_first, +- field_value_length, true, total_line_length, false); ++ field_value_length, raw_print_field, total_line_length, false); + mime_hdr_field_attach(mh, field, 1, nullptr); + } + } diff -Nru trafficserver-8.1.1+ds/debian/patches/0019-CVE_2021_37148.patch trafficserver-8.1.1+ds/debian/patches/0019-CVE_2021_37148.patch --- trafficserver-8.1.1+ds/debian/patches/0019-CVE_2021_37148.patch 1970-01-01 00:00:00.000000000 +0000 +++ trafficserver-8.1.1+ds/debian/patches/0019-CVE_2021_37148.patch 2022-05-21 17:28:31.000000000 +0000 @@ -0,0 +1,37 @@ +Description: Reject Transfer-Encoding in pre-HTTP/1.1 requests + Per spec, Transfer-Encoding is only supported in HTTP/1.1. For earlier + versions, we must reject Transfer-Encoding rather than interpret it + since downstream proxies may ignore the chunk header and rely upon the + Content-Length, or interpret the body some other way. These differences + in interpretation may open up the door to compatibility issues. To + protect against this, we reply with a 4xx if the client uses + Transfer-Encoding with HTTP versions that do not support it. +Author: Brian Neradt +Origin: upstream +Applied-Upstream: https://github.com/apache/trafficserver/commit/e2c9ac217f24dc3e91ff2c9f52b52093e8fb32d5 +Reviewed-by: Jean Baptiste Favre +Last-Update: 2022-05-21 +--- +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ +Index: trafficserver/proxy/http/HttpTransact.cc +=================================================================== +--- trafficserver.orig/proxy/http/HttpTransact.cc 2022-05-21 18:55:58.801202772 +0200 ++++ trafficserver/proxy/http/HttpTransact.cc 2022-05-21 19:06:47.056189813 +0200 +@@ -5174,6 +5174,17 @@ + return BAD_CONNECT_PORT; + } + ++ if (s->client_info.transfer_encoding == CHUNKED_ENCODING && incoming_hdr->version_get() < HTTPVersion(1, 1)) { ++ // Per spec, Transfer-Encoding is only supported in HTTP/1.1. For earlier ++ // versions, we must reject Transfer-Encoding rather than interpret it ++ // since downstream proxies may ignore the chunk header and rely upon the ++ // Content-Length, or interpret the body some other way. These ++ // differences in interpretation may open up the door to compatibility ++ // issues. To protect against this, we reply with a 4xx if the client ++ // uses Transfer-Encoding with HTTP versions that do not support it. ++ return UNACCEPTABLE_TE_REQUIRED; ++ } ++ + // Require Content-Length/Transfer-Encoding for POST/PUSH/PUT + if ((scheme == URL_WKSIDX_HTTP || scheme == URL_WKSIDX_HTTPS) && + (method == HTTP_WKSIDX_POST || method == HTTP_WKSIDX_PUSH || method == HTTP_WKSIDX_PUT) && diff -Nru trafficserver-8.1.1+ds/debian/patches/0019-CVE_2021_37149.patch trafficserver-8.1.1+ds/debian/patches/0019-CVE_2021_37149.patch --- trafficserver-8.1.1+ds/debian/patches/0019-CVE_2021_37149.patch 1970-01-01 00:00:00.000000000 +0000 +++ trafficserver-8.1.1+ds/debian/patches/0019-CVE_2021_37149.patch 2022-05-21 17:28:31.000000000 +0000 @@ -0,0 +1,235 @@ +Description: Detect and handle chunk header size truncation + This detects if a chunk header size is too large and, if so, closes the + connection. +Author: Brian Neradt +Origin: upstream +Applied-Upstream: https://github.com/apache/trafficserver/commit/2addc8ca71449ceac0d5b80172460ee09c938f5e +Reviewed-by: Jean Baptiste Favre +Last-Update: 2022-05-21 +--- +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ +Index: trafficserver/include/tscore/ink_memory.h +=================================================================== +--- trafficserver.orig/include/tscore/ink_memory.h 2022-05-21 18:55:58.637203619 +0200 ++++ trafficserver/include/tscore/ink_memory.h 2022-05-21 19:10:10.978804602 +0200 +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -204,6 +205,24 @@ + memset(static_cast(&t), 0, sizeof(t)); + } + ++/** Verify that we can safely shift value num_places places left. ++ * ++ * This checks that the shift will not cause the variable to overflow and that ++ * the value will not become negative. ++ * ++ * @param[in] value The value against which to check whether the shift is safe. ++ * ++ * @param[in] num_places The number of places to check that shifting left is safe. ++ * ++ */ ++template ++inline constexpr bool ++can_safely_shift_left(T value, int num_places) ++{ ++ constexpr auto max_value = std::numeric_limits::max(); ++ return value >= 0 && value <= (max_value >> num_places); ++} ++ + /** Scoped resources. + + An instance of this class is used to hold a contingent resource. When this object goes out of scope +Index: trafficserver/proxy/http/HttpTunnel.cc +=================================================================== +--- trafficserver.orig/proxy/http/HttpTunnel.cc 2022-05-21 18:55:58.801202772 +0200 ++++ trafficserver/proxy/http/HttpTunnel.cc 2022-05-21 19:10:10.982804575 +0200 +@@ -36,6 +36,7 @@ + #include "HttpSM.h" + #include "HttpDebugNames.h" + #include "tscore/ParseRules.h" ++#include "tscore/ink_memory.h" + + static const int min_block_transfer_bytes = 256; + static const char *const CHUNK_HEADER_FMT = "%" PRIx64 "\r\n"; +@@ -153,8 +154,16 @@ + if (state == CHUNK_READ_SIZE) { + // The http spec says the chunked size is always in hex + if (ParseRules::is_hex(*tmp)) { ++ // Make sure we will not overflow running_sum with our shift. ++ if (!can_safely_shift_left(running_sum, 4)) { ++ // We have no more space in our variable for the shift. ++ state = CHUNK_READ_ERROR; ++ done = true; ++ break; ++ } + num_digits++; +- running_sum *= 16; ++ // Shift over one hex value. ++ running_sum <<= 4; + + if (ParseRules::is_digit(*tmp)) { + running_sum += *tmp - '0'; +Index: trafficserver/src/tscore/Makefile.am +=================================================================== +--- trafficserver.orig/src/tscore/Makefile.am 2022-05-21 18:55:58.853202502 +0200 ++++ trafficserver/src/tscore/Makefile.am 2022-05-21 19:10:10.982804575 +0200 +@@ -258,6 +258,7 @@ + unit_tests/test_BufferWriter.cc \ + unit_tests/test_BufferWriterFormat.cc \ + unit_tests/test_ink_inet.cc \ ++ unit_tests/test_ink_memory.cc \ + unit_tests/test_IntrusivePtr.cc \ + unit_tests/test_IpMap.cc \ + unit_tests/test_layout.cc \ +Index: trafficserver/src/tscore/unit_tests/test_ink_memory.cc +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ trafficserver/src/tscore/unit_tests/test_ink_memory.cc 2022-05-21 19:10:10.982804575 +0200 +@@ -0,0 +1,141 @@ ++/** @file ++ ++ ink_memory unit tests. ++ ++ @section license License ++ ++ 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. ++*/ ++ ++#include ++#include ++#include "tscore/ink_memory.h" ++ ++constexpr void ++test_can_safely_shift_int8_t() ++{ ++ constexpr int8_t a = 0; ++ static_assert(can_safely_shift_left(a, 0) == true, "shifting 0 is safe"); ++ static_assert(can_safely_shift_left(a, 4) == true, "shifting 0 is safe"); ++ static_assert(can_safely_shift_left(a, 8) == true, "shifting 0 is safe"); ++ ++ constexpr int8_t b = 1; ++ static_assert(can_safely_shift_left(b, 0) == true, "shifting int8_t 1 0 places is safe"); ++ static_assert(can_safely_shift_left(b, 1) == true, "shifting int8_t 1 1 places is safe"); ++ static_assert(can_safely_shift_left(b, 6) == true, "shifting int8_t 1 6 places is safe"); ++ static_assert(can_safely_shift_left(b, 7) == false, "shifting int8_t 1 7 places becomes negative"); ++ static_assert(can_safely_shift_left(b, 8) == false, "shifting int8_t 1 8 places overflows"); ++ ++ constexpr int8_t c = 0xff; ++ static_assert(can_safely_shift_left(c, 0) == false, "int8_t 0xff is already negative"); ++ static_assert(can_safely_shift_left(c, 1) == false, "shifting int8_t 0xff 1 place overflows"); ++} ++ ++constexpr void ++test_can_safely_shift_uint8_t() ++{ ++ constexpr uint8_t a = 0; ++ static_assert(can_safely_shift_left(a, 0) == true, "shifting 0 is safe"); ++ static_assert(can_safely_shift_left(a, 4) == true, "shifting 0 is safe"); ++ static_assert(can_safely_shift_left(a, 8) == true, "shifting 0 is safe"); ++ ++ constexpr uint8_t b = 1; ++ static_assert(can_safely_shift_left(b, 0) == true, "shifting uint8_t 1 0 places is safe"); ++ static_assert(can_safely_shift_left(b, 1) == true, "shifting uint8_t 1 1 places is safe"); ++ static_assert(can_safely_shift_left(b, 6) == true, "shifting uint8_t 1 6 places is safe"); ++ static_assert(can_safely_shift_left(b, 7) == true, "shifting uint8_t 1 7 is safe"); ++ static_assert(can_safely_shift_left(b, 8) == false, "shifting uint8_t 1 8 places overflows"); ++ ++ constexpr uint8_t c = 0xff; ++ static_assert(can_safely_shift_left(c, 0) == true, "shifting int8_t 0xff 0 places is safe"); ++ static_assert(can_safely_shift_left(c, 1) == false, "shifting int8_t 0xff 1 place overflows"); ++} ++ ++constexpr void ++test_can_safely_shift_int32_t() ++{ ++ constexpr int32_t a = 0; ++ static_assert(can_safely_shift_left(a, 4) == true, "shifting 0 is safe"); ++ ++ constexpr int32_t b = 1; ++ static_assert(can_safely_shift_left(b, 4) == true, "shifting 1 is safe"); ++ ++ constexpr int32_t c = 0x00ff'ffff; ++ static_assert(can_safely_shift_left(c, 4) == true, "shifting 0x00ff'ffff is safe"); ++ ++ constexpr int32_t d = 0x07ff'ffff; ++ static_assert(can_safely_shift_left(d, 4) == true, "shifting 0x07ff'ffff is safe"); ++ ++ constexpr int32_t e = -1; ++ static_assert(can_safely_shift_left(e, 4) == false, "shifting -1 will result in truncation"); ++ ++ constexpr int32_t f = 0x0800'0000; ++ static_assert(can_safely_shift_left(f, 4) == false, "shifting 0x0801'0000 will become negative"); ++ ++ constexpr int32_t g = 0x0fff'ffff; ++ static_assert(can_safely_shift_left(g, 4) == false, "shifting 0x0fff'ffff will become negative"); ++ ++ constexpr int32_t h = 0x1000'0000; ++ static_assert(can_safely_shift_left(h, 4) == false, "shifting 0x1000'0000 will overflow"); ++ ++ constexpr int32_t i = 0xf000'0000; ++ static_assert(can_safely_shift_left(i, 4) == false, "shifting 0xf000'0000 will overflow"); ++ ++ constexpr int32_t j = 0xf800'0000; ++ static_assert(can_safely_shift_left(j, 4) == false, "shifting 0xf800'0000 will become negative"); ++} ++ ++constexpr void ++test_can_safely_shift_uint32_t() ++{ ++ constexpr uint32_t a = 0; ++ static_assert(can_safely_shift_left(a, 4) == true, "shifting 0 is safe"); ++ ++ constexpr uint32_t b = 1; ++ static_assert(can_safely_shift_left(b, 4) == true, "shifting 1 is safe"); ++ ++ constexpr uint32_t c = 0x00ff'ffff; ++ static_assert(can_safely_shift_left(c, 4) == true, "shifting 0x00ff'ffff is safe"); ++ ++ constexpr uint32_t d = 0x07ff'ffff; ++ static_assert(can_safely_shift_left(d, 4) == true, "shifting 0x07ff'ffff is safe"); ++ ++ constexpr uint32_t e = 0x0800'0000; ++ static_assert(can_safely_shift_left(e, 4) == true, "shifting unisgned 0x0800'0000 is safe"); ++ ++ constexpr uint32_t f = 0x0fff'ffff; ++ static_assert(can_safely_shift_left(f, 4) == true, "shifting unsigned 0x0fff'ffff is safe"); ++ ++ constexpr uint32_t g = 0x1000'0000; ++ static_assert(can_safely_shift_left(g, 4) == false, "shifting 0x1000'0000 will overflow"); ++ ++ constexpr uint32_t h = 0xf000'0000; ++ static_assert(can_safely_shift_left(h, 4) == false, "shifting 0xf000'0000 will overflow"); ++ ++ constexpr uint32_t i = 0xf800'0000; ++ static_assert(can_safely_shift_left(i, 4) == false, "shifting 0xf800'0000 will become negative"); ++} ++ ++TEST_CASE("can_safely_shift", "[libts][ink_inet][memory]") ++{ ++ // can_safely_shift_left is a constexpr function, therefore all these checks are ++ // done at compile time and REQUIRES calls are not necessary. ++ test_can_safely_shift_int8_t(); ++ test_can_safely_shift_uint8_t(); ++ test_can_safely_shift_int32_t(); ++ test_can_safely_shift_uint32_t(); ++} diff -Nru trafficserver-8.1.1+ds/debian/patches/0019-CVE_2021_38161.patch trafficserver-8.1.1+ds/debian/patches/0019-CVE_2021_38161.patch --- trafficserver-8.1.1+ds/debian/patches/0019-CVE_2021_38161.patch 1970-01-01 00:00:00.000000000 +0000 +++ trafficserver-8.1.1+ds/debian/patches/0019-CVE_2021_38161.patch 2022-05-21 17:28:31.000000000 +0000 @@ -0,0 +1,30 @@ +Description: Add some checking to validate the scheme matches the wire protocol. +Author: Alan M. Carroll +Origin: upstream +Applied-Upstream: https://github.com/apache/trafficserver/commit/feefc5e4abc5011dfad5dcfef3f22998faf6e2d4 +Reviewed-by: Jean Baptiste Favre +Last-Update: 2022-05-21 +--- +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ +Index: trafficserver/proxy/http/HttpSM.cc +=================================================================== +--- trafficserver.orig/proxy/http/HttpSM.cc 2022-05-21 18:55:58.793202813 +0200 ++++ trafficserver/proxy/http/HttpSM.cc 2022-05-21 19:12:07.438046649 +0200 +@@ -732,6 +732,17 @@ + case PARSE_RESULT_DONE: + SMDebug("http", "[%" PRId64 "] done parsing client request header", sm_id); + ++ if (!is_internal) { ++ auto scheme = t_state.hdr_info.client_request.url_get()->scheme_get_wksidx(); ++ if ((client_connection_is_ssl && (scheme == URL_WKSIDX_HTTP || scheme == URL_WKSIDX_WS)) || ++ (!client_connection_is_ssl && (scheme == URL_WKSIDX_HTTPS || scheme == URL_WKSIDX_WSS))) { ++ SMDebug("http", "scheme [%s] vs. protocol [%s] mismatch", hdrtoken_index_to_wks(scheme), ++ client_connection_is_ssl ? "tls" : "plaintext"); ++ t_state.http_return_code = HTTP_STATUS_BAD_REQUEST; ++ call_transact_and_set_next_state(HttpTransact::BadRequest); ++ break; ++ } ++ } + ua_txn->set_session_active(); + + if (t_state.hdr_info.client_request.version_get() == HTTPVersion(1, 1) && diff -Nru trafficserver-8.1.1+ds/debian/patches/0019-CVE_2021_44040.patch trafficserver-8.1.1+ds/debian/patches/0019-CVE_2021_44040.patch --- trafficserver-8.1.1+ds/debian/patches/0019-CVE_2021_44040.patch 1970-01-01 00:00:00.000000000 +0000 +++ trafficserver-8.1.1+ds/debian/patches/0019-CVE_2021_44040.patch 2022-05-21 17:28:31.000000000 +0000 @@ -0,0 +1,513 @@ +Description: Improper Input Validation vulnerability in request line parsing +Author: +Origin: upstream +Applied-Upstream: 85c319a7f7c0537bee408ea25df6f1a5ed0a4071, c4e6661a5a205b1f60279f0e66aa496023185967, 8c6f2ed84ba0d8e6255baceb99ee891ebe1ce473 +Reviewed-by: Jean Baptiste Favre +Last-Update: 2022-05-21 +--- +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ +Index: trafficserver/doc/admin-guide/files/records.config.en.rst +=================================================================== +--- trafficserver.orig/doc/admin-guide/files/records.config.en.rst 2022-05-21 19:01:54.422372252 +0200 ++++ trafficserver/doc/admin-guide/files/records.config.en.rst 2022-05-21 19:18:52.251530553 +0200 +@@ -1134,10 +1134,12 @@ + An arbitrary string value that, if set, will be used to replace any request + ``User-Agent`` header. + +-.. ts:cv:: CONFIG proxy.config.http.strict_uri_parsing INT 0 ++.. ts:cv:: CONFIG proxy.config.http.strict_uri_parsing INT 2 + +- Enables (``1``) or disables (``0``) Traffic Server to return a 400 Bad Request +- if client's request URI includes character which is not RFC 3986 compliant ++ Takes a value between 0 and 2. ``0`` disables strict_uri_parsing. Any character can appears ++ in the URI. ``1`` causes |TS| to return 400 Bad Request ++ if client's request URI includes character which is not RFC 3986 compliant. ``2`` directs |TS| ++ to reject the clients request if it contains whitespace or non-printable characters. + + .. ts:cv:: CONFIG proxy.config.http.errors.log_error_pages INT 1 + :reloadable: +Index: trafficserver/mgmt/RecordsConfig.cc +=================================================================== +--- trafficserver.orig/mgmt/RecordsConfig.cc 2022-05-21 18:55:58.701203288 +0200 ++++ trafficserver/mgmt/RecordsConfig.cc 2022-05-21 19:18:52.251530553 +0200 +@@ -354,7 +354,7 @@ + , + {RECT_CONFIG, "proxy.config.http.post.check.content_length.enabled", RECD_INT, "1", RECU_DYNAMIC, RR_NULL, RECC_INT, "[0-1]", RECA_NULL} + , +- {RECT_CONFIG, "proxy.config.http.strict_uri_parsing", RECD_INT, "0", RECU_DYNAMIC, RR_NULL, RECC_INT, "[0-1]", RECA_NULL} ++ {RECT_CONFIG, "proxy.config.http.strict_uri_parsing", RECD_INT, "2", RECU_DYNAMIC, RR_NULL, RECC_INT, "[0-2]", RECA_NULL} + , + // # Send http11 requests + // # +Index: trafficserver/proxy/hdrs/HTTP.cc +=================================================================== +--- trafficserver.orig/proxy/hdrs/HTTP.cc 2022-05-21 18:55:58.781202874 +0200 ++++ trafficserver/proxy/hdrs/HTTP.cc 2022-05-21 19:18:41.927593091 +0200 +@@ -885,7 +885,7 @@ + + ParseResult + http_parser_parse_req(HTTPParser *parser, HdrHeap *heap, HTTPHdrImpl *hh, const char **start, const char *end, +- bool must_copy_strings, bool eof, bool strict_uri_parsing) ++ bool must_copy_strings, bool eof, int strict_uri_parsing) + { + if (parser->m_parsing_http) { + MIMEScanner *scanner = &parser->m_mime_parser.m_scanner; +Index: trafficserver/proxy/hdrs/HTTP.h +=================================================================== +--- trafficserver.orig/proxy/hdrs/HTTP.h 2022-05-21 18:55:58.781202874 +0200 ++++ trafficserver/proxy/hdrs/HTTP.h 2022-05-21 19:18:41.927593091 +0200 +@@ -445,7 +445,7 @@ + void http_parser_init(HTTPParser *parser); + void http_parser_clear(HTTPParser *parser); + ParseResult http_parser_parse_req(HTTPParser *parser, HdrHeap *heap, HTTPHdrImpl *hh, const char **start, const char *end, +- bool must_copy_strings, bool eof, bool strict_uri_parsing); ++ bool must_copy_strings, bool eof, int strict_uri_parsing); + ParseResult validate_hdr_host(HTTPHdrImpl *hh); + ParseResult validate_hdr_content_length(HdrHeap *heap, HTTPHdrImpl *hh); + ParseResult http_parser_parse_resp(HTTPParser *parser, HdrHeap *heap, HTTPHdrImpl *hh, const char **start, const char *end, +@@ -624,10 +624,10 @@ + const char *reason_get(int *length); + void reason_set(const char *value, int length); + +- ParseResult parse_req(HTTPParser *parser, const char **start, const char *end, bool eof, bool strict_uri_parsing = false); ++ ParseResult parse_req(HTTPParser *parser, const char **start, const char *end, bool eof, int strict_uri_parsing = 0); + ParseResult parse_resp(HTTPParser *parser, const char **start, const char *end, bool eof); + +- ParseResult parse_req(HTTPParser *parser, IOBufferReader *r, int *bytes_used, bool eof, bool strict_uri_parsing = false); ++ ParseResult parse_req(HTTPParser *parser, IOBufferReader *r, int *bytes_used, bool eof, int strict_uri_parsing = 0); + ParseResult parse_resp(HTTPParser *parser, IOBufferReader *r, int *bytes_used, bool eof); + + public: +@@ -1225,7 +1225,7 @@ + -------------------------------------------------------------------------*/ + + inline ParseResult +-HTTPHdr::parse_req(HTTPParser *parser, const char **start, const char *end, bool eof, bool strict_uri_parsing) ++HTTPHdr::parse_req(HTTPParser *parser, const char **start, const char *end, bool eof, int strict_uri_parsing) + { + ink_assert(valid()); + ink_assert(m_http->m_polarity == HTTP_TYPE_REQUEST); +Index: trafficserver/proxy/hdrs/HdrTSOnly.cc +=================================================================== +--- trafficserver.orig/proxy/hdrs/HdrTSOnly.cc 2022-05-21 18:55:58.781202874 +0200 ++++ trafficserver/proxy/hdrs/HdrTSOnly.cc 2022-05-21 19:18:41.927593091 +0200 +@@ -45,7 +45,7 @@ + -------------------------------------------------------------------------*/ + + ParseResult +-HTTPHdr::parse_req(HTTPParser *parser, IOBufferReader *r, int *bytes_used, bool eof, bool strict_uri_parsing) ++HTTPHdr::parse_req(HTTPParser *parser, IOBufferReader *r, int *bytes_used, bool eof, int strict_uri_parsing) + { + const char *start; + const char *tmp; +Index: trafficserver/proxy/hdrs/URL.cc +=================================================================== +--- trafficserver.orig/proxy/hdrs/URL.cc 2022-05-21 18:55:58.789202833 +0200 ++++ trafficserver/proxy/hdrs/URL.cc 2022-05-21 19:18:41.927593091 +0200 +@@ -1179,10 +1179,34 @@ + return true; + } + ++/** ++ * This method will return TRUE if the uri is mostly compliant with ++ * RFC 3986 and it will return FALSE if not. Specifically denying white ++ * space an unprintable characters ++ */ ++static bool ++url_is_mostly_compliant(const char *start, const char *end) ++{ ++ for (const char *i = start; i < end; ++i) { ++ if (isspace(*i)) { ++ Debug("http", "Whitespace character [0x%.2X] found in URL", (unsigned char)*i); ++ return false; ++ } ++ if (!isprint(*i)) { ++ Debug("http", "Non-printable character [0x%.2X] found in URL", (unsigned char)*i); ++ return false; ++ } ++ } ++ return true; ++} ++ + ParseResult +-url_parse(HdrHeap *heap, URLImpl *url, const char **start, const char *end, bool copy_strings_p, bool strict_uri_parsing) ++url_parse(HdrHeap *heap, URLImpl *url, const char **start, const char *end, bool copy_strings_p, int strict_uri_parsing) + { +- if (strict_uri_parsing && !url_is_strictly_compliant(*start, end)) { ++ if (strict_uri_parsing == 1 && !url_is_strictly_compliant(*start, end)) { ++ return PARSE_RESULT_ERROR; ++ } ++ if (strict_uri_parsing == 2 && !url_is_mostly_compliant(*start, end)) { + return PARSE_RESULT_ERROR; + } + +Index: trafficserver/proxy/hdrs/URL.h +=================================================================== +--- trafficserver.orig/proxy/hdrs/URL.h 2022-05-21 18:55:58.789202833 +0200 ++++ trafficserver/proxy/hdrs/URL.h 2022-05-21 19:18:41.927593091 +0200 +@@ -198,14 +198,13 @@ + void url_fragment_set(HdrHeap *heap, URLImpl *url, const char *value, int length, bool copy_string); + + ParseResult url_parse(HdrHeap *heap, URLImpl *url, const char **start, const char *end, bool copy_strings, +- bool strict_uri_parsing = false); ++ int strict_uri_parsing = false); + ParseResult url_parse_no_path_component_breakdown(HdrHeap *heap, URLImpl *url, const char **start, const char *end, + bool copy_strings); + ParseResult url_parse_internet(HdrHeap *heap, URLImpl *url, const char **start, const char *end, bool copy_strings); + ParseResult url_parse_http(HdrHeap *heap, URLImpl *url, const char **start, const char *end, bool copy_strings); + ParseResult url_parse_http_no_path_component_breakdown(HdrHeap *heap, URLImpl *url, const char **start, const char *end, + bool copy_strings); +- + char *url_unescapify(Arena *arena, const char *str, int length); + + void unescape_str(char *&buf, char *buf_e, const char *&str, const char *str_e, int &state); +Index: trafficserver/proxy/http/HttpConfig.cc +=================================================================== +--- trafficserver.orig/proxy/http/HttpConfig.cc 2022-05-21 18:55:58.789202833 +0200 ++++ trafficserver/proxy/http/HttpConfig.cc 2022-05-21 19:18:41.927593091 +0200 +@@ -1473,7 +1473,7 @@ + params->referer_filter_enabled = INT_TO_BOOL(m_master.referer_filter_enabled); + params->referer_format_redirect = INT_TO_BOOL(m_master.referer_format_redirect); + +- params->strict_uri_parsing = INT_TO_BOOL(m_master.strict_uri_parsing); ++ params->strict_uri_parsing = m_master.strict_uri_parsing; + + params->oride.down_server_timeout = m_master.oride.down_server_timeout; + params->oride.client_abort_threshold = m_master.oride.client_abort_threshold; +Index: trafficserver/proxy/http/HttpConfig.h +=================================================================== +--- trafficserver.orig/proxy/http/HttpConfig.h 2022-05-21 18:55:58.789202833 +0200 ++++ trafficserver/proxy/http/HttpConfig.h 2022-05-21 19:18:52.251530553 +0200 +@@ -847,7 +847,7 @@ + MgmtByte referer_filter_enabled = 0; + MgmtByte referer_format_redirect = 0; + +- MgmtByte strict_uri_parsing = 0; ++ MgmtByte strict_uri_parsing = 2; + + MgmtByte reverse_proxy_enabled = 0; + MgmtByte url_remap_required = 1; +Index: trafficserver/tests/gold_tests/headers/gold/bad_good_request.gold +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ trafficserver/tests/gold_tests/headers/gold/bad_good_request.gold 2022-05-21 19:18:41.931593066 +0200 +@@ -0,0 +1,9 @@ ++``HTTP/1.1 400 Invalid HTTP Request ++``Connection: close ++``Server: ATS/`` ++``Content-Length: 219 ++`` ++Bad Request ++``

Bad Request

++``Description: Could not process this request. ++`` +Index: trafficserver/tests/gold_tests/headers/gold/bad_good_request_header.gold +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ trafficserver/tests/gold_tests/headers/gold/bad_good_request_header.gold 2022-05-21 19:18:41.931593066 +0200 +@@ -0,0 +1,5 @@ ++``HTTP/1.1 400 Invalid HTTP Request ++``Connection: close ++``Server: ATS/`` ++``Content-Length: 219 ++`` +Index: trafficserver/tests/gold_tests/headers/gold/bad_good_request_http1.gold +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ trafficserver/tests/gold_tests/headers/gold/bad_good_request_http1.gold 2022-05-21 19:18:41.931593066 +0200 +@@ -0,0 +1,8 @@ ++``HTTP/1.0 400 Invalid HTTP Request ++``Server: ATS/`` ++``Content-Length: 219 ++`` ++Bad Request ++``

Bad Request

++``Description: Could not process this request. ++`` +Index: trafficserver/tests/gold_tests/headers/gold/bad_method.gold +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ trafficserver/tests/gold_tests/headers/gold/bad_method.gold 2022-05-21 19:18:41.931593066 +0200 +@@ -0,0 +1,24 @@ ++HTTP/1.1 501 Unsupported method ('gET') ++Content-Type: text/html;charset=utf-8 ++Content-Length: 496 ++Date: `` ++Age: 0 ++Connection: keep-alive ++Server: ATS/`` ++ ++ ++ ++ ++ ++ Error response ++ ++ ++

Error response

++

Error code: 501

++

Message: Unsupported method ('gET').

++

Error code explanation: HTTPStatus.NOT_IMPLEMENTED - Server does not support this operation.

++ ++ ++HTTP/1.1 200 OK ++`` +Index: trafficserver/tests/gold_tests/headers/gold/bad_protocol_number.gold +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ trafficserver/tests/gold_tests/headers/gold/bad_protocol_number.gold 2022-05-21 19:18:41.931593066 +0200 +@@ -0,0 +1,22 @@ ++HTTP/1.1 505 Unsupported HTTP Version ++Date: `` ++Server: ATS/`` ++Cache-Control: no-store ++Content-Type: text/html ++Content-Language: en ++Content-Length: 219 ++ ++ ++ ++Bad Request ++ ++ ++ ++

Bad Request

++
++ ++ ++Description: Could not process this request. ++ ++
++ +Index: trafficserver/tests/gold_tests/headers/gold/bad_te_value.gold +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ trafficserver/tests/gold_tests/headers/gold/bad_te_value.gold 2022-05-21 19:18:41.931593066 +0200 +@@ -0,0 +1,25 @@ ++HTTP/1.1 501 Field not implemented ++Date: `` ++Connection: keep-alive ++Server: ATS/`` ++Cache-Control: no-store ++Content-Type: text/html ++Content-Language: en ++Content-Length: 289 ++ ++ ++ ++Transcoding Not Available ++ ++ ++ ++

Transcoding Not Available

++
++ ++ ++ ++ Description: Unable to provide the document in the ++format requested by your browser. ++ ++
++ +Index: trafficserver/tests/gold_tests/headers/good_request_after_bad.test.py +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ trafficserver/tests/gold_tests/headers/good_request_after_bad.test.py 2022-05-21 19:18:41.931593066 +0200 +@@ -0,0 +1,196 @@ ++''' ++Verify that request following a ill-formed request is not processed ++''' ++# 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 = ''' ++Verify that request following a ill-formed request is not processed ++''' ++Test.ContinueOnFail = True ++ts = Test.MakeATSProcess("ts") ++Test.ContinueOnFail = True ++ts.Disk.records_config.update({'proxy.config.diags.debug.tags': 'http', ++ 'proxy.config.diags.debug.enabled': 0, ++ 'proxy.config.http.strict_uri_parsing': 1 ++ }) ++ ++ts2 = Test.MakeATSProcess("ts2") ++ ++ts2.Disk.records_config.update({'proxy.config.diags.debug.tags': 'http', ++ 'proxy.config.diags.debug.enabled': 0, ++ 'proxy.config.http.strict_uri_parsing': 2 ++ }) ++ ++ ++server = Test.MakeOriginServer("server") ++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\nLast-Modified: Tue, 08 May 2018 15:49:41 GMT\r\nCache-Control: max-age=1000\r\n\r\n", ++ "timestamp": "1469733493.993", ++ "body": "xxx"} ++server.addResponse("sessionlog.json", request_header, response_header) ++ ++ts.Disk.remap_config.AddLine( ++ 'map / http://127.0.0.1:{0}'.format(server.Variables.Port) ++) ++ts.Disk.remap_config.AddLine( ++ 'map /bob<> http://127.0.0.1:{0}'.format(server.Variables.Port) ++) ++ts2.Disk.remap_config.AddLine( ++ 'map / http://127.0.0.1:{0}'.format(server.Variables.Port) ++) ++ts2.Disk.remap_config.AddLine( ++ 'map /bob<> http://127.0.0.1:{0}'.format(server.Variables.Port) ++) ++ ++trace_out = Test.Disk.File("trace_curl.txt") ++ ++# Make a good request to get item in the cache for later tests ++tr = Test.AddTestRun("Good control") ++tr.Processes.Default.StartBefore(server) ++tr.Processes.Default.StartBefore(Test.Processes.ts) ++tr.Processes.Default.Command = 'printf "GET / HTTP/1.1\r\nHost: bob\r\n\r\n" | nc 127.0.0.1 {}'.format(ts.Variables.port) ++tr.Processes.Default.ReturnCode = 0 ++ ++tr = Test.AddTestRun("Good control") ++tr.Processes.Default.StartBefore(server) ++tr.Processes.Default.StartBefore(Test.Processes.ts2) ++tr.Processes.Default.Command = 'printf "GET / HTTP/1.1\r\nHost: bob\r\n\r\n" | nc 127.0.0.1 {}'.format(ts2.Variables.port) ++tr.Processes.Default.ReturnCode = 0 ++ ++tr = Test.AddTestRun("space after header name") ++tr.Processes.Default.Command = 'printf "GET / HTTP/1.1\r\nHost : bob\r\n\r\nGET / HTTP/1.1\r\nHost: boa\r\n\r\n" | nc 127.0.0.1 {}'.format( ++ ts.Variables.port) ++tr.Processes.Default.ReturnCode = 0 ++tr.Processes.Default.Streams.stdout = 'gold/bad_good_request.gold' ++ ++# Commenting out a bunch of tests on master whose fixes are not in 8.1.x. ++#tr = Test.AddTestRun("Bad protocol number") ++#tr.Processes.Default.Command = 'printf "GET / HTTP/11.1\r\nhost: bob\r\n\r\nGET / HTTP/1.1\r\nHost: boa\r\n\r\n" | nc 127.0.0.1 {}'.format( ++# ts.Variables.port) ++#tr.Processes.Default.ReturnCode = 0 ++#tr.Processes.Default.Streams.stdout = 'gold/bad_protocol_number.gold' ++# ++#tr = Test.AddTestRun("Unsupported Transfer Encoding value") ++#tr.Processes.Default.Command = 'printf "GET / HTTP/1.1\r\nhost: bob\r\ntransfer-encoding: random\r\n\r\nGET / HTTP/1.1\r\nHost: boa\r\n\r\n" | nc 127.0.0.1 {}'.format( ++# ts.Variables.port) ++#tr.Processes.Default.ReturnCode = 0 ++#tr.Processes.Default.Streams.stdout = 'gold/bad_te_value.gold' ++# ++#tr = Test.AddTestRun("Another unsupported Transfer Encoding value") ++#tr.Processes.Default.Command = 'printf "GET / HTTP/1.1\r\nhost: bob\r\ntransfer-encoding: \x08chunked\r\n\r\nGET / HTTP/1.1\r\nHost: boa\r\n\r\n" | nc 127.0.0.1 {}'.format( ++# ts.Variables.port) ++#tr.Processes.Default.ReturnCode = 0 ++#tr.Processes.Default.Streams.stdout = 'gold/bad_te_value.gold' ++# ++#tr = Test.AddTestRun("Extra characters in content-length") ++#tr.Processes.Default.Command = 'printf "GET / HTTP/1.1\r\nhost: bob\r\ncontent-length:+3\r\n\r\nGET / HTTP/1.1\r\nHost: boa\r\n\r\n" | nc 127.0.0.1 {}'.format( ++# ts.Variables.port) ++#tr.Processes.Default.ReturnCode = 0 ++#tr.Processes.Default.Streams.stdout = 'gold/bad_good_request_header.gold' ++# ++#tr = Test.AddTestRun("Different extra characters in content-length") ++#tr.Processes.Default.Command = 'printf "GET / HTTP/1.1\r\nhost: bob\r\ncontent-length:\x0c3\r\n\r\nGET / HTTP/1.1\r\nHost: boa\r\n\r\n" | nc 127.0.0.1 {}'.format( ++# ts.Variables.port) ++#tr.Processes.Default.ReturnCode = 0 ++#tr.Processes.Default.Streams.stdout = 'gold/bad_good_request_header.gold' ++# ++# ++## TRACE request with a body ++#tr = Test.AddTestRun("Trace request with a body") ++#tr.Processes.Default.Command = 'printf "TRACE /foo HTTP/1.1\r\nHost: bob\r\nContent-length:2\r\n\r\nokGET / HTTP/1.1\r\nHost: boa\r\n\r\n" | nc 127.0.0.1 {}'.format( ++# ts.Variables.port) ++#tr.Processes.Default.ReturnCode = 0 ++#tr.Processes.Default.Streams.stdout = 'gold/bad_good_request.gold' ++# ++#tr = Test.AddTestRun("Trace request with a chunked body") ++#tr.Processes.Default.Command = 'printf "TRACE /foo HTTP/1.1\r\nHost: bob\r\ntransfer-encoding: chunked\r\n\r\n2\r\nokGGET / HTTP/1.1\r\nHost: boa\r\n\r\n" | nc 127.0.0.1 {}'.format( ++# ts.Variables.port) ++#tr.Processes.Default.ReturnCode = 0 ++#tr.Processes.Default.Streams.stdout = 'gold/bad_good_request.gold' ++# ++#tr = Test.AddTestRun("Trace request with a chunked body via curl") ++#tr.Processes.Default.Command = 'curl -v --http1.1 --header "Transfer-Encoding: chunked" -d aaa -X TRACE -o trace_curl.txt -k http://127.0.0.1:{}/foo'.format( ++# ts.Variables.port) ++#tr.Processes.Default.ReturnCode = 0 ++#tr.Processes.Default.Streams.All = 'gold/bad_good_request_header.gold' ++#trace_out.Content = Testers.ContainsExpression("Bad Request", "ATS error msg") ++#trace_out.Content += Testers.ContainsExpression("Description: Could not process this request.", "ATS error msg") ++# ++#tr = Test.AddTestRun("Trace request via curl") ++#tr.Processes.Default.Command = 'curl -v --http1.1 -X TRACE -k http://127.0.0.1:{}/bar'.format(ts.Variables.port) ++#tr.Processes.Default.ReturnCode = 0 ++#tr.Processes.Default.Streams.All = Testers.ContainsExpression( ++# r"HTTP/1.1 501 Unsupported method \('TRACE'\)", ++# "microserver does not support TRACE") ++# ++## Methods are case sensitive. Verify that "gET" is not confused with "GET". ++#tr = Test.AddTestRun("mixed case method") ++#tr.Processes.Default.Command = 'printf "gET / HTTP/1.1\r\nHost:bob\r\n\r\nGET / HTTP/1.1\r\nHost: boa\r\n\r\n" | nc 127.0.0.1 {}'.format( ++# ts.Variables.port) ++#tr.Processes.Default.ReturnCode = 0 ++#tr.Processes.Default.Streams.stdout = 'gold/bad_method.gold' ++# ++## mangled termination ++#tr = Test.AddTestRun("mangled line termination") ++#tr.Processes.Default.Command = 'printf "GET / HTTP/1.1\r\nHost:bob\r\n \r\nGET / HTTP/1.1\r\nHost: boa\r\n\r\n" | nc 127.0.0.1 {}'.format( ++# ts.Variables.port) ++#tr.Processes.Default.ReturnCode = 0 ++#tr.Processes.Default.Streams.stdout = 'gold/bad_good_request.gold' ++ ++tr = Test.AddTestRun("Catch bad URL characters") ++tr.Processes.Default.Command = 'printf "GET /bob<> HTTP/1.1\r\nhost: bob\r\n\r\nGET / HTTP/1.1\r\nHost: boa\r\n\r\n" | nc 127.0.0.1 {}'.format( ++ ts.Variables.port) ++tr.Processes.Default.ReturnCode = 0 ++# Since the request line is messsed up ATS will reply with HTTP/1.0 ++tr.Processes.Default.Streams.stdout = 'gold/bad_good_request_http1.gold' ++ ++tr = Test.AddTestRun("Catch whitespace in URL") ++tr.Processes.Default.Command = 'printf "GET /bob foo HTTP/1.1\r\nhost: bob\r\n\r\nGET / HTTP/1.1\r\nHost: boa\r\n\r\n" | nc 127.0.0.1 {}'.format( ++ ts.Variables.port) ++tr.Processes.Default.ReturnCode = 0 ++# Since the request line is messsed up ATS will reply with HTTP/1.0 ++tr.Processes.Default.Streams.stdout = 'gold/bad_good_request_http1.gold' ++ ++tr = Test.AddTestRun("Extra characters in protocol") ++tr.Processes.Default.Command = 'printf "GET / HTP/1.1\r\nhost: bob\r\n\r\nGET / HTTP/1.1\r\nHost: boa\r\n\r\n" | nc 127.0.0.1 {}'.format( ++ ts.Variables.port) ++tr.Processes.Default.ReturnCode = 0 ++# Since the request line is messsed up ATS will reply with HTTP/1.0 ++tr.Processes.Default.Streams.stdout = 'gold/bad_good_request_http1.gold' ++ ++tr = Test.AddTestRun("Characters that are strict but not case 2 bad") ++tr.Processes.Default.Command = 'printf "GET /bob<> HTTP/1.1\r\nhost: bob\r\n\r\nGET / HTTP/1.1\r\nHost: boa\r\n\r\n" | nc 127.0.0.1 {}'.format( ++ ts2.Variables.port) ++tr.Processes.Default.ReturnCode = 0 ++tr.Processes.Default.Streams.All = Testers.ContainsExpression("HTTP/1.1 200 OK", "Success") ++ ++tr = Test.AddTestRun("Catch whitespace in URL") ++tr.Processes.Default.Command = 'printf "GET /bob foo HTTP/1.1\r\nhost: bob\r\n\r\nGET / HTTP/1.1\r\nHost: boa\r\n\r\n" | nc 127.0.0.1 {}'.format( ++ ts2.Variables.port) ++tr.Processes.Default.ReturnCode = 0 ++# Since the request line is messsed up ATS will reply with HTTP/1.0 ++tr.Processes.Default.Streams.stdout = 'gold/bad_good_request_http1.gold' ++ ++tr = Test.AddTestRun("Extra characters in protocol") ++tr.Processes.Default.Command = 'printf "GET / HTP/1.1\r\nhost: bob\r\n\r\nGET / HTTP/1.1\r\nHost: boa\r\n\r\n" | nc 127.0.0.1 {}'.format( ++ ts2.Variables.port) ++tr.Processes.Default.ReturnCode = 0 ++# Since the request line is messsed up ATS will reply with HTTP/1.0 ++tr.Processes.Default.Streams.stdout = 'gold/bad_good_request_http1.gold' diff -Nru trafficserver-8.1.1+ds/debian/patches/0019-CVE_2021_44759.patch trafficserver-8.1.1+ds/debian/patches/0019-CVE_2021_44759.patch --- trafficserver-8.1.1+ds/debian/patches/0019-CVE_2021_44759.patch 1970-01-01 00:00:00.000000000 +0000 +++ trafficserver-8.1.1+ds/debian/patches/0019-CVE_2021_44759.patch 2022-05-21 17:28:31.000000000 +0000 @@ -0,0 +1,79 @@ +Description: Bug fix in origin connection handling +Origin: upstream +Applied-Upstream: https://github.com/apache/trafficserver/commit/d3f36f79820ea10c26573c742b1bbc370c351716 +Reviewed-by: Jean Baptiste Favre +Last-Update: 2022-05-21 +--- +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ +Index: trafficserver/iocore/net/SSLNetVConnection.cc +=================================================================== +--- trafficserver.orig/iocore/net/SSLNetVConnection.cc 2022-05-21 18:55:58.677203412 +0200 ++++ trafficserver/iocore/net/SSLNetVConnection.cc 2022-05-21 19:22:11.594334167 +0200 +@@ -1041,8 +1041,7 @@ + // Making the check here instead of later, so we only + // do this setting immediately after we create the SSL object + SNIConfig::scoped_config sniParam; +- int8_t clientVerify = 0; +- cchar *serverKey = this->options.sni_servername; ++ cchar *serverKey = this->options.sni_servername; + if (!serverKey) { + ats_ip_ntop(this->get_remote_addr(), buff, INET6_ADDRSTRLEN); + serverKey = buff; +@@ -1051,25 +1050,30 @@ + SSL_CTX *clientCTX = nullptr; + + if (nps) { +- clientCTX = nps->ctx; +- clientVerify = nps->verifyLevel; ++ clientCTX = nps->ctx; + } else { + clientCTX = params->client_ctx; +- // Keeping backwards compatability on the proxy.config.ssl.client.verify.server setting +- clientVerify = params->clientVerify ? (params->clientVerify == 1 ? 2 : 1) : 0; + } ++ + if (!clientCTX) { + SSLErrorVC(this, "failed to create SSL client session"); + return EVENT_ERROR; + } + ++ if (nps && nps->verifyLevel != static_cast(YamlSNIConfig::Level::UNSET)) { ++ this->options.clientVerificationFlag = nps->verifyLevel; ++ } else { ++ // Keeping backwards compatibility on the proxy.config.ssl.client.verify.server setting ++ this->options.clientVerificationFlag = params->clientVerify ? (params->clientVerify == 1 ? 2 : 1) : 0; ++ } ++ + this->ssl = make_ssl_connection(clientCTX, this); + if (this->ssl == nullptr) { + SSLErrorVC(this, "failed to create SSL client session"); + return EVENT_ERROR; + } + int verify_op; +- if (clientVerify) { ++ if (this->options.clientVerificationFlag) { + verify_op = SSL_VERIFY_PEER; + SSL_set_verify(this->ssl, verify_op, verify_callback); + } else { +Index: trafficserver/iocore/net/YamlSNIConfig.h +=================================================================== +--- trafficserver.orig/iocore/net/YamlSNIConfig.h 2022-05-21 18:55:58.681203391 +0200 ++++ trafficserver/iocore/net/YamlSNIConfig.h 2022-05-21 19:22:11.594334167 +0200 +@@ -45,7 +45,7 @@ + client_cert + + }; +- enum class Level { NONE = 0, MODERATE, STRICT }; ++ enum class Level { NONE = 0, MODERATE, STRICT, UNSET }; + enum class TLSProtocol : uint8_t { TLSv1 = 0, TLSv1_1, TLSv1_2, TLSv1_3, TLS_MAX = TLSv1_3 }; + + YamlSNIConfig() {} +@@ -55,7 +55,7 @@ + bool disable_h2 = false; + uint8_t verify_client_level = 0; + std::string tunnel_destination; +- uint8_t verify_origin_server = 0; ++ uint8_t verify_origin_server = static_cast(Level::UNSET); + std::string client_cert; + std::string ip_allow; + bool protocol_unset = true; diff -Nru trafficserver-8.1.1+ds/debian/patches/series trafficserver-8.1.1+ds/debian/patches/series --- trafficserver-8.1.1+ds/debian/patches/series 2021-07-15 19:45:33.000000000 +0000 +++ trafficserver-8.1.1+ds/debian/patches/series 2022-05-21 17:28:31.000000000 +0000 @@ -11,3 +11,9 @@ 0016-fix_python_3.8.patch 0017-fix_sphinx_3.0.patch 0018-Fixes-7971.patch +0019-CVE_2021_37147.patch +0019-CVE_2021_37148.patch +0019-CVE_2021_37149.patch +0019-CVE_2021_38161.patch +0019-CVE_2021_44040.patch +0019-CVE_2021_44759.patch