1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
From 67bf97cd1dfa513c8b6374905ee225b4d46cdf20 Mon Sep 17 00:00:00 2001
From: Sam Bull <git@sambull.org>
Date: Mon, 13 Nov 2023 22:13:06 +0000
Subject: [PATCH] Disallow arbitrary sequence types in version (#7835)
Upstream-Status: Backport
[https://github.com/aio-libs/aiohttp/commit/1e86b777e61cf4eefc7d92fa57fa19dcc676013b]
CVE: CVE-2023-49081
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Signed-off-by: Jiaying Song <jiaying.song.cn@windriver.com>
---
CHANGES/7835.bugfix | 1 +
aiohttp/client_reqrep.py | 4 ++--
tests/test_client_request.py | 18 +++++++++++++++---
3 files changed, 18 insertions(+), 5 deletions(-)
create mode 100644 CHANGES/7835.bugfix
diff --git a/CHANGES/7835.bugfix b/CHANGES/7835.bugfix
new file mode 100644
index 0000000..4ce3af4
--- /dev/null
+++ b/CHANGES/7835.bugfix
@@ -0,0 +1 @@
+Fixed arbitrary sequence types being allowed to inject headers via version parameter -- by :user:`Dreamsorcerer`
diff --git a/aiohttp/client_reqrep.py b/aiohttp/client_reqrep.py
index 987d68f..d3cd77e 100644
--- a/aiohttp/client_reqrep.py
+++ b/aiohttp/client_reqrep.py
@@ -661,8 +661,8 @@ class ClientRequest:
self.headers[hdrs.CONNECTION] = connection
# status + headers
- status_line = "{0} {1} HTTP/{2[0]}.{2[1]}".format(
- self.method, path, self.version
+ status_line = "{0} {1} HTTP/{v.major}.{v.minor}".format(
+ self.method, path, v=self.version
)
await writer.write_headers(status_line, self.headers)
diff --git a/tests/test_client_request.py b/tests/test_client_request.py
index 9eeb933..009f1a0 100644
--- a/tests/test_client_request.py
+++ b/tests/test_client_request.py
@@ -20,6 +20,7 @@ from aiohttp.client_reqrep import (
_merge_ssl_params,
)
from aiohttp.helpers import PY_311
+from aiohttp.http import HttpVersion
from aiohttp.test_utils import make_mocked_coro
@@ -576,18 +577,18 @@ async def test_connection_header(loop, conn) -> None:
req.headers.clear()
req.keep_alive.return_value = True
- req.version = (1, 1)
+ req.version = HttpVersion(1, 1)
req.headers.clear()
await req.send(conn)
assert req.headers.get("CONNECTION") is None
- req.version = (1, 0)
+ req.version = HttpVersion(1, 0)
req.headers.clear()
await req.send(conn)
assert req.headers.get("CONNECTION") == "keep-alive"
req.keep_alive.return_value = False
- req.version = (1, 1)
+ req.version = HttpVersion(1, 1)
req.headers.clear()
await req.send(conn)
assert req.headers.get("CONNECTION") == "close"
@@ -1113,6 +1114,17 @@ async def test_close(loop, buf, conn) -> None:
await req.close()
resp.close()
+async def test_bad_version(loop: Any, conn: Any) -> None:
+ req = ClientRequest(
+ "GET",
+ URL("http://python.org"),
+ loop=loop,
+ headers={"Connection": "Close"},
+ version=("1", "1\r\nInjected-Header: not allowed"),
+ )
+
+ with pytest.raises(AttributeError):
+ await req.send(conn)
async def test_custom_response_class(loop, conn) -> None:
class CustomResponse(ClientResponse):
--
2.25.1
|