trafficserver/CVE-2024-38311-pre-Do-not-allow-extra-CRs-in-chunks-11936-11942.patch
starlet-dx 0af0d27de3 Fix CVE-2024-38311,CVE-2024-56195 and CVE-2024-56202
(cherry picked from commit 1be79f85e0ecdd6927504eaa16b594d42a1beba1)
2025-03-07 10:53:04 +08:00

169 lines
6.0 KiB
Diff

From d3fd9ac0380099de6bb1fb973234aa278000aecc Mon Sep 17 00:00:00 2001
From: Masakazu Kitajo <maskit@apache.org>
Date: Wed, 15 Jan 2025 11:10:36 -0700
Subject: [PATCH] Do not allow extra CRs in chunks (#11936) (#11942)
* Do not allow extra CRs in chunks (#11936)
* Do not allow extra CRs in chunks
* Renumber test uuid
* Add test cases and fix an oversight
* Use prefix increment
(cherry picked from commit f5f2256c00abbfd02c22fbae3937da1c7bd8a34f)
* Fix test case
---
proxy/http/HttpTunnel.cc | 12 +++++
.../bad_chunked_encoding.test.py | 6 +--
.../malformed_chunked_header.replay.yaml | 49 +++++++++++++++++--
3 files changed, 61 insertions(+), 6 deletions(-)
diff --git a/proxy/http/HttpTunnel.cc b/proxy/http/HttpTunnel.cc
index 4b20784f395..adb3cd9bc98 100644
--- a/proxy/http/HttpTunnel.cc
+++ b/proxy/http/HttpTunnel.cc
@@ -136,6 +136,7 @@ ChunkedHandler::read_size()
{
int64_t bytes_used;
bool done = false;
+ int cr = 0;
while (chunked_reader->read_avail() > 0 && !done) {
const char *tmp = chunked_reader->start();
@@ -174,6 +175,9 @@ ChunkedHandler::read_size()
done = true;
break;
} else {
+ if (ParseRules::is_cr(*tmp)) {
+ ++cr;
+ }
state = CHUNK_READ_SIZE_CRLF; // now look for CRLF
}
}
@@ -183,7 +187,15 @@ ChunkedHandler::read_size()
cur_chunk_bytes_left = (cur_chunk_size = running_sum);
state = (running_sum == 0) ? CHUNK_READ_TRAILER_BLANK : CHUNK_READ_CHUNK;
done = true;
+ cr = 0;
break;
+ } else if (ParseRules::is_cr(*tmp)) {
+ if (cr != 0) {
+ state = CHUNK_READ_ERROR;
+ done = true;
+ break;
+ }
+ ++cr;
}
} else if (state == CHUNK_READ_SIZE_START) {
if (ParseRules::is_cr(*tmp)) {
diff --git a/tests/gold_tests/chunked_encoding/bad_chunked_encoding.test.py b/tests/gold_tests/chunked_encoding/bad_chunked_encoding.test.py
index e92181ccdf7..f22cb9d2d39 100644
--- a/tests/gold_tests/chunked_encoding/bad_chunked_encoding.test.py
+++ b/tests/gold_tests/chunked_encoding/bad_chunked_encoding.test.py
@@ -172,13 +172,13 @@ def runChunkedTraffic(self):
# code from the verifier client.
tr.Processes.Default.ReturnCode = 1
tr.Processes.Default.Streams.stdout += Testers.ContainsExpression(
- r"(Unexpected chunked content for key 4: too small|Failed HTTP/1 transaction with key: 4)",
+ r"(Unexpected chunked content for key 101: too small|Failed HTTP/1 transaction with key: 101)",
"Verify that ATS closed the forth transaction.")
tr.Processes.Default.Streams.stdout += Testers.ContainsExpression(
- r"(Unexpected chunked content for key 5: too small|Failed HTTP/1 transaction with key: 5)",
+ r"(Unexpected chunked content for key 102: too small|Failed HTTP/1 transaction with key: 102)",
"Verify that ATS closed the fifth transaction.")
tr.Processes.Default.Streams.stdout += Testers.ContainsExpression(
- r"(Unexpected chunked content for key 6: too small|Failed HTTP/1 transaction with key: 6)",
+ r"(Unexpected chunked content for key 103: too small|Failed HTTP/1 transaction with key: 103)",
"Verify that ATS closed the sixth transaction.")
# ATS should close the connection before any body gets through. "def"
diff --git a/tests/gold_tests/chunked_encoding/replays/malformed_chunked_header.replay.yaml b/tests/gold_tests/chunked_encoding/replays/malformed_chunked_header.replay.yaml
index ae135d77ab7..5f136a7eeba 100644
--- a/tests/gold_tests/chunked_encoding/replays/malformed_chunked_header.replay.yaml
+++ b/tests/gold_tests/chunked_encoding/replays/malformed_chunked_header.replay.yaml
@@ -78,6 +78,26 @@ sessions:
server-response:
status: 200
+- transactions:
+ - client-request:
+ method: "POST"
+ version: "1.1"
+ url: /malformed/chunk/header3
+ headers:
+ fields:
+ - [ Host, example.com ]
+ - [ Transfer-Encoding, chunked ]
+ - [ uuid, 4 ]
+ content:
+ transfer: plain
+ encoding: uri
+ # BWS cannot have CR
+ data: 3%0D%0D%0Aabc%0D%0A0%0D%0A%0D%0A
+
+ # The connection will be dropped and this response will not go out.
+ server-response:
+ status: 200
+
#
# Now repeat the above two malformed chunk header tests, but on the server
# side.
@@ -90,7 +110,7 @@ sessions:
headers:
fields:
- [ Host, example.com ]
- - [ uuid, 4 ]
+ - [ uuid, 101 ]
# The connection will be dropped and this response will not go out.
server-response:
@@ -113,7 +133,7 @@ sessions:
headers:
fields:
- [ Host, example.com ]
- - [ uuid, 5 ]
+ - [ uuid, 102 ]
# The connection will be dropped and this response will not go out.
server-response:
@@ -136,7 +156,7 @@ sessions:
headers:
fields:
- [ Host, example.com ]
- - [ uuid, 6 ]
+ - [ uuid, 103 ]
# The connection will be dropped and this response will not go out.
server-response:
@@ -150,3 +170,26 @@ sessions:
encoding: uri
# Super large chunk header, larger than will fit in an int.
data: 111111113%0D%0Adef%0D%0A0%0D%0A%0D%0A
+
+- transactions:
+ - client-request:
+ method: "GET"
+ version: "1.1"
+ url: /response/malformed/chunk/size2
+ headers:
+ fields:
+ - [ Host, example.com ]
+ - [ uuid, 104 ]
+
+ # The connection will be dropped and this response will not go out.
+ server-response:
+ status: 200
+ reason: OK
+ headers:
+ fields:
+ - [ Transfer-Encoding, chunked ]
+ content:
+ transfer: plain
+ encoding: uri
+ # BWS cannot have CR
+ data: 3%0D%0D%0Adef%0D%0A0%0D%0A%0D%0A