diff --git a/CHANGES/10142.bugfix.rst b/CHANGES/10142.bugfix.rst new file mode 100644 index 00000000000..a295fe6e31e --- /dev/null +++ b/CHANGES/10142.bugfix.rst @@ -0,0 +1 @@ +Improved error message for HTTPS requests sent to an HTTP port by detecting the TLS handshake bytes. -- by :user:`NIK-TIGER-BILL`. diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index c3c16f82eee..0551572daf7 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -283,6 +283,7 @@ Moss Collum Mun Gwan-gyeong Navid Sheikhol Nicolas Braem +NIK-TIGER-BILL Nikolay Kim Nikolay Novik Nikolay Tiunov diff --git a/aiohttp/http_parser.py b/aiohttp/http_parser.py index d0aee4d75c4..c16119918ae 100644 --- a/aiohttp/http_parser.py +++ b/aiohttp/http_parser.py @@ -577,6 +577,18 @@ class HttpRequestParser(HttpParser[RawRequestMessage]): def parse_message(self, lines: list[bytes]) -> RawRequestMessage: # request line line = lines[0].decode("utf-8", "surrogateescape") + if lines[0].startswith(b"\x16\x03"): + raise BadHttpMethod( + line, + error="Client appears to be trying to connect via HTTPS to an HTTP port", + ) + + if lines[0].startswith(b"\x16\x03"): + raise BadHttpMethod( + line, + error="Client appears to be trying to connect via HTTPS to an HTTP port", + ) + try: method, path, version = line.split(" ", maxsplit=2) except ValueError: diff --git a/tests/test_http_parser.py b/tests/test_http_parser.py index 1bf80d271c3..c96527baafb 100644 --- a/tests/test_http_parser.py +++ b/tests/test_http_parser.py @@ -1170,6 +1170,22 @@ def test_http_request_parser_bad_method( parser.feed_data(rfc9110_5_6_2_token_delim + b'ET" /get HTTP/1.1\r\n\r\n') +def test_http_request_parser_bad_method_https_on_http_port( + parser: HttpRequestParser, +) -> None: + with pytest.raises(http_exceptions.BadHttpMethod) as exc_info: + parser.feed_data(b"\x16\x03\x01\x00\xa5\x01\x00\x00\xa1\x03\x03") + assert "HTTPS" in str(exc_info.value) + + +def test_http_request_parser_bad_method_https_on_http_port( + parser: HttpRequestParser, +) -> None: + with pytest.raises(http_exceptions.BadHttpMethod) as exc_info: + parser.feed_data(b"\x16\x03\x01\x00\xa5\x01\x00\x00\xa1\x03\x03") + assert "HTTPS" in str(exc_info.value) + + def test_http_request_parser_bad_version(parser: HttpRequestParser) -> None: with pytest.raises(http_exceptions.BadHttpMessage): parser.feed_data(b"GET //get HT/11\r\n\r\n")