File CVE-2021-39214.patch of Package python-mitmproxy.18041
From b41416b729214e14300ee25df706c907a0fdb008 Mon Sep 17 00:00:00 2001
From: Maximilian Hils <git@maximilianhils.com>
Date: Thu, 16 Sep 2021 11:12:59 +0200
Subject: [PATCH] Merge pull request from GHSA-22gh-3r9q-xf38
This commit makes mitmproxy hard-fail when it encounters any attempts
at request/response smuggling.
For details, see https://github.com/mitmproxy/mitmproxy/security/advisories/GHSA-22gh-3r9q-xf38
---
mitmproxy/net/http/http1/read.py | 104 ++++++++++++++++--
mitmproxy/proxy/layers/http/_http1.py | 18 +--
mitmproxy/proxy/layers/http/_http2.py | 4 +-
test/mitmproxy/net/http/http1/test_read.py | 32 +++++-
test/mitmproxy/proxy/layers/http/test_http.py | 29 +++++
.../mitmproxy/proxy/layers/http/test_http2.py | 49 +++++++++
6 files changed, 210 insertions(+), 26 deletions(-)
Index: mitmproxy-3.0.4/mitmproxy/net/http/http1/read.py
===================================================================
--- mitmproxy-3.0.4.orig/mitmproxy/net/http/http1/read.py
+++ mitmproxy-3.0.4/mitmproxy/net/http/http1/read.py
@@ -201,13 +201,43 @@ def expected_http_body_size(request, res
return 0
if 100 <= response_code <= 199:
return 0
- if response_code == 200 and request.method.upper() == "CONNECT":
- return 0
if response_code in (204, 304):
return 0
+ if 200 <= response.code <= 299 and request.method.upper() == "CONNECT":
+ return 0
+
+ if "transfer-encoding" in headers:
+ if "content-length" in headers:
+ raise ValueError("Received both a Transfer-Encoding and a Content-Length header, "
+ "refusing as recommended in RFC 7230 Section 3.3.3. "
+ "See https://github.com/mitmproxy/mitmproxy/issues/4799 for details.")
+
+ te: str = headers["transfer-encoding"]
+ if not te.isascii():
+ # guard against .lower() transforming non-ascii to ascii
+ raise ValueError(f"Invalid transfer encoding: {te!r}")
+ te = te.lower().strip("\t ")
+ te = re.sub(r"[\t ]*,[\t ]*", ",", te)
+ if te in (
+ "chunked",
+ "compress,chunked",
+ "deflate,chunked",
+ "gzip,chunked",
+ ):
+ return None
+ elif te in (
+ "compress",
+ "deflate",
+ "gzip",
+ "identity",
+ ):
+ if response:
+ return -1
+ else:
+ raise ValueError(f"Invalid request transfer encoding, message body cannot be determined reliably.")
+ else:
+ raise ValueError(f"Unknown transfer encoding: {headers['transfer-encoding']!r}")
- if "chunked" in headers.get("transfer-encoding", "").lower():
- return None
if "content-length" in headers:
try:
sizes = headers.get_all("content-length")
Index: mitmproxy-3.0.4/mitmproxy/proxy/protocol/http2.py
===================================================================
--- mitmproxy-3.0.4.orig/mitmproxy/proxy/protocol/http2.py
+++ mitmproxy-3.0.4/mitmproxy/proxy/protocol/http2.py
@@ -98,7 +98,7 @@ class Http2Layer(base.Layer):
client_side=False,
header_encoding=False,
validate_outbound_headers=False,
- validate_inbound_headers=False)
+ validate_inbound_headers=True)
self.connections[self.client_conn] = SafeH2Connection(self.client_conn, config=config)
def _initiate_server_conn(self):
@@ -107,7 +107,7 @@ class Http2Layer(base.Layer):
client_side=True,
header_encoding=False,
validate_outbound_headers=False,
- validate_inbound_headers=False)
+ validate_inbound_headers=True)
self.connections[self.server_conn] = SafeH2Connection(self.server_conn, config=config)
self.connections[self.server_conn].initiate_connection()
self.server_conn.send(self.connections[self.server_conn].data_to_send())