Skip to content

Commit 01e91fc

Browse files
authored
Ensure provided uris match their normalized version (#9)
* Ensure provided uris match their normalized version * not endswith rather then not equals
1 parent 97abc64 commit 01e91fc

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

aiohasupervisor/client.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,17 @@ async def _request(
7070
data: Any = None,
7171
) -> Response:
7272
"""Handle a request to Supervisor."""
73-
url = URL(self.api_host).joinpath(uri)
73+
try:
74+
url = URL(self.api_host).joinpath(uri)
75+
except ValueError as err:
76+
raise SupervisorError from err
77+
78+
# This check is to make sure the normalized URL string is the same as the URL
79+
# string that was passed in. If they are different, then the passed in uri
80+
# contained characters that were removed by the normalization
81+
# such as ../../../../etc/passwd
82+
if not url.raw_path.endswith(uri):
83+
raise SupervisorError(f"Invalid request {uri}")
7484

7585
match response_type:
7686
case ResponseType.TEXT:

tests/test_client.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
"""Tests for client."""
2+
3+
import pytest
4+
5+
from aiohasupervisor.client import _SupervisorClient
6+
from aiohasupervisor.exceptions import SupervisorError
7+
8+
from .const import SUPERVISOR_URL
9+
10+
11+
@pytest.mark.parametrize("method", ["get", "post", "put", "delete"])
12+
async def test_path_manipulation_blocked(method: str) -> None:
13+
"""Test path manipulation prevented."""
14+
client = _SupervisorClient(SUPERVISOR_URL, "abc123", 10)
15+
action = getattr(client, method)
16+
with pytest.raises(SupervisorError):
17+
# absolute path
18+
await action("/test/../bad")
19+
with pytest.raises(SupervisorError):
20+
# relative path
21+
await action("test/../bad")
22+
with pytest.raises(SupervisorError):
23+
# relative path with percent encoding
24+
await action("test/%2E%2E/bad")

0 commit comments

Comments
 (0)