mirror of
https://github.com/openembedded/meta-openembedded.git
synced 2026-11-14 03:57:15 +00:00
python3-aiohttp: fix CVE-2026-111750
Backport the upstream HEAD request parsing fix [1] to aiohttp 3.13.5, as identified by [2]. Only responses to HEAD may skip their body; incoming HEAD requests must consume the declared request body. Retain the upstream regression that embeds a request in a HEAD body and verifies that the following request remains correctly framed. The pure-Python parser remains available with extensions installed. [1] https://github.com/aio-libs/aiohttp/commit/9b27347e61454d9f8ca2055f4c67a37dee336e83 [2] https://github.com/aio-libs/aiohttp/security/advisories/GHSA-pqxq-w44r-73xw Signed-off-by: Darsh Kelaiya <dkelaiya@cisco.com> Signed-off-by: Anuj Mittal <anuj.mittal@oss.qualcomm.com>
This commit is contained in:
1 parent
ba8d0af836
commit
e04156eb37
2 files changed
+84
No files matched your search
@@ -0,0 +1,83 @@
|
||||
From 9b27347e61454d9f8ca2055f4c67a37dee336e83 Mon Sep 17 00:00:00 2001
|
||||
From: Sam Bull <git@sambull.org>
|
||||
Date: Wed, 9 Sep 2026 01:25:13 +0100
|
||||
Subject: [PATCH] Fix head request parsing (#13671) (#13673)
|
||||
|
||||
(cherry picked from commit 5789546e37fe35af27d0a2f840870b22bc15bfc4)
|
||||
|
||||
CVE: CVE-2026-111750
|
||||
Upstream-Status: Backport [https://github.com/aio-libs/aiohttp/commit/9b27347e61454d9f8ca2055f4c67a37dee336e83]
|
||||
|
||||
Signed-off-by: Darsh Kelaiya <dkelaiya@cisco.com>
|
||||
---
|
||||
CHANGES/13671.bugfix.rst | 1 +
|
||||
aiohttp/http_parser.py | 6 +++++-
|
||||
tests/test_http_parser.py | 27 ++++++++++++++++++++++++++-
|
||||
3 files changed, 32 insertions(+), 2 deletions(-)
|
||||
create mode 100644 CHANGES/13671.bugfix.rst
|
||||
|
||||
diff --git a/CHANGES/13671.bugfix.rst b/CHANGES/13671.bugfix.rst
|
||||
new file mode 100644
|
||||
index 0000000..e6fbc70
|
||||
--- /dev/null
|
||||
+++ b/CHANGES/13671.bugfix.rst
|
||||
@@ -0,0 +1 @@
|
||||
+Fixed pure-Python request parser not reading a body in a ``HEAD`` request -- by :user:`Dreamsorcerer`.
|
||||
diff --git a/aiohttp/http_parser.py b/aiohttp/http_parser.py
|
||||
index f4458dc..ce15764 100644
|
||||
--- a/aiohttp/http_parser.py
|
||||
+++ b/aiohttp/http_parser.py
|
||||
@@ -426,8 +426,12 @@ class HttpParser(abc.ABC, Generic[_MsgT]):
|
||||
|
||||
assert self.protocol is not None
|
||||
# calculate payload
|
||||
+ # https://www.rfc-editor.org/info/rfc9112/#name-message-body-length
|
||||
+ # https://www.rfc-editor.org/info/rfc9110/#section-9.3.1-6
|
||||
+ # EMPTY_BODY_METHODS should only apply to responses.
|
||||
+ # self.method is None on request parser.
|
||||
empty_body = code in EMPTY_BODY_STATUS_CODES or bool(
|
||||
- method and method in EMPTY_BODY_METHODS
|
||||
+ self.method and self.method in EMPTY_BODY_METHODS
|
||||
)
|
||||
if not empty_body and (
|
||||
(length is not None and length > 0) or msg.chunked
|
||||
diff --git a/tests/test_http_parser.py b/tests/test_http_parser.py
|
||||
index 4cdd94c..4255f4d 100644
|
||||
--- a/tests/test_http_parser.py
|
||||
+++ b/tests/test_http_parser.py
|
||||
@@ -1781,7 +1781,32 @@ def test_http_request_chunked_payload_and_next_message(parser) -> None:
|
||||
assert not payload2.is_eof()
|
||||
|
||||
|
||||
-def test_http_request_chunked_payload_chunks(parser) -> None:
|
||||
+def test_http_request_parser_head_with_content_length_payload(
|
||||
+ parser: HttpRequestParser,
|
||||
+) -> None:
|
||||
+ smuggled = b"GET /smuggled HTTP/1.1\r\nHost: a\r\n\r\n"
|
||||
+ text = (
|
||||
+ b"HEAD /test HTTP/1.1\r\nHost: a\r\nContent-Length: %d\r\n\r\n" % len(smuggled)
|
||||
+ + smuggled
|
||||
+ + b"POST /next HTTP/1.1\r\nHost: a\r\nContent-Length: 0\r\n\r\n"
|
||||
+ )
|
||||
+ messages, upgraded, tail = parser.feed_data(text)
|
||||
+
|
||||
+ assert len(messages) == 2
|
||||
+ msg, payload = messages[0]
|
||||
+ assert msg.method == "HEAD"
|
||||
+ assert b"".join(payload._buffer) == smuggled
|
||||
+ assert payload.is_eof()
|
||||
+
|
||||
+ msg2, payload2 = messages[1]
|
||||
+ assert msg2.method == "POST"
|
||||
+ assert msg2.path == "/next"
|
||||
+ assert payload2.is_eof()
|
||||
+ assert not upgraded
|
||||
+ assert not tail
|
||||
+
|
||||
+
|
||||
+def test_http_request_chunked_payload_chunks(parser: HttpRequestParser) -> None:
|
||||
text = b"GET /test HTTP/1.1\r\ntransfer-encoding: chunked\r\n\r\n"
|
||||
msg, payload = parser.feed_data(text)[0][0]
|
||||
|
||||
--
|
||||
2.35.6
|
||||
@@ -24,6 +24,7 @@ SRC_URI += " \
|
||||
file://CVE-2026-69244.patch \
|
||||
file://CVE-2026-111066_p1.patch \
|
||||
file://CVE-2026-111066_p2.patch \
|
||||
file://CVE-2026-111750.patch \
|
||||
"
|
||||
|
||||
CVE_PRODUCT = "aiohttp:aiohttp"
|
||||
|
||||
Reference in new issue
Block a user