From 165b996316290cc9ca9ab32a3be2cd7288288c90 Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Wed, 19 Jan 2022 18:05:49 +0200 Subject: [PATCH 1/6] Add HTTP method validation --- aiohttp/client_reqrep.py | 10 +++++++++- tests/test_client_request.py | 5 +++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/aiohttp/client_reqrep.py b/aiohttp/client_reqrep.py index 7344ce24431..d54fffa0aaa 100644 --- a/aiohttp/client_reqrep.py +++ b/aiohttp/client_reqrep.py @@ -84,6 +84,9 @@ from .tracing import Trace +_CONTAINS_CONTROL_CHAR_RE = re.compile(r"[^-!#$%&'*+.^_`|~0-9a-zA-Z]") + + def _gen_default_accept_encoding() -> str: return "gzip, deflate, br" if HAS_BROTLI else "gzip, deflate" @@ -208,7 +211,12 @@ def __init__( proxy_headers: Optional[LooseHeaders] = None, traces: Optional[List["Trace"]] = None, ): - + match = _CONTAINS_CONTROL_CHAR_RE.search(method) + if match: + raise ValueError( + f"Method cannot contain non-token characters {method!r} " + "(found at least {match.group()!r})" + ) assert isinstance(url, URL), url assert isinstance(proxy, (URL, type(None))), proxy # FIXME: session is None in tests only, need to fix tests diff --git a/tests/test_client_request.py b/tests/test_client_request.py index 733922dff72..f756e10f29e 100644 --- a/tests/test_client_request.py +++ b/tests/test_client_request.py @@ -88,6 +88,11 @@ def test_method3(make_request: Any) -> None: assert req.method == "HEAD" +def test_method3_invalid(make_request: Any) -> None: + with pytest.raises(ValueError): + make_request("METHOD WITH\nWHITESPACES", "http://python.org/") + + def test_version_1_0(make_request: Any) -> None: req = make_request("get", "http://python.org/", version="1.0") assert req.version == (1, 0) From 344e0b2214112fa89f415b7957ab8cfd1d4cb67d Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Wed, 19 Jan 2022 18:06:57 +0200 Subject: [PATCH 2/6] Add changelog --- CHANGES/6533.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 CHANGES/6533.feature diff --git a/CHANGES/6533.feature b/CHANGES/6533.feature new file mode 100644 index 00000000000..4f3a640721b --- /dev/null +++ b/CHANGES/6533.feature @@ -0,0 +1 @@ +Add HTTP method validation From 894d3ea813e3b44ff1b0da7e1f41fc70b8975f2b Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Wed, 19 Jan 2022 19:01:37 +0200 Subject: [PATCH 3/6] Fix test --- tests/test_web_request.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/test_web_request.py b/tests/test_web_request.py index 9a89bf7f30a..71e46a93e2d 100644 --- a/tests/test_web_request.py +++ b/tests/test_web_request.py @@ -46,7 +46,9 @@ def test_base_ctor() -> None: assert "GET" == req.method assert HttpVersion(1, 1) == req.version - assert req.host == socket.getfqdn() + # FQDN can be wider than host, e.g. + # 'fv-az397-495' in 'fv-az397-495.internal.cloudapp.net' + assert req.host in socket.getfqdn() assert "/path/to?a=1&b=2" == req.path_qs assert "/path/to" == req.path assert "a=1&b=2" == req.query_string From 415755d98463e58cdfdd3405f4575262e47168ab Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Wed, 19 Jan 2022 19:27:58 +0200 Subject: [PATCH 4/6] Fix test --- tests/test_client_request.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_client_request.py b/tests/test_client_request.py index f756e10f29e..6810efd7cb5 100644 --- a/tests/test_client_request.py +++ b/tests/test_client_request.py @@ -88,8 +88,8 @@ def test_method3(make_request: Any) -> None: assert req.method == "HEAD" -def test_method3_invalid(make_request: Any) -> None: - with pytest.raises(ValueError): +def test_method_invalid(make_request: Any) -> None: + with pytest.raises(ValueError, match="Method cannot contain non-token characters"): make_request("METHOD WITH\nWHITESPACES", "http://python.org/") From ebef2f2a4cfaef2ebaa8ebf7e2c73ecf4d3180ba Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Wed, 19 Jan 2022 19:50:27 +0200 Subject: [PATCH 5/6] Fix tests --- tests/test_web_request.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/test_web_request.py b/tests/test_web_request.py index 71e46a93e2d..9b20fd03717 100644 --- a/tests/test_web_request.py +++ b/tests/test_web_request.py @@ -46,9 +46,10 @@ def test_base_ctor() -> None: assert "GET" == req.method assert HttpVersion(1, 1) == req.version + # MacOS may return CamelCased host name, need .lower() # FQDN can be wider than host, e.g. # 'fv-az397-495' in 'fv-az397-495.internal.cloudapp.net' - assert req.host in socket.getfqdn() + assert req.host.lower() in socket.getfqdn().lower() assert "/path/to?a=1&b=2" == req.path_qs assert "/path/to" == req.path assert "a=1&b=2" == req.query_string @@ -73,7 +74,9 @@ def test_ctor() -> None: assert "GET" == req.method assert HttpVersion(1, 1) == req.version # MacOS may return CamelCased host name, need .lower() - assert req.host.lower() == socket.getfqdn().lower() + # FQDN can be wider than host, e.g. + # 'fv-az397-495' in 'fv-az397-495.internal.cloudapp.net' + assert req.host.lower() in socket.getfqdn().lower() assert "/path/to?a=1&b=2" == req.path_qs assert "/path/to" == req.path assert "a=1&b=2" == req.query_string From 3720febc1b80b341e7a209ef3da77cb13b23dcaa Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Wed, 19 Jan 2022 20:04:03 +0200 Subject: [PATCH 6/6] add a dot --- CHANGES/6533.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES/6533.feature b/CHANGES/6533.feature index 4f3a640721b..36bcbeb21dc 100644 --- a/CHANGES/6533.feature +++ b/CHANGES/6533.feature @@ -1 +1 @@ -Add HTTP method validation +Add HTTP method validation.