File tree Expand file tree Collapse file tree 3 files changed +45
-1
lines changed
Expand file tree Collapse file tree 3 files changed +45
-1
lines changed Original file line number Diff line number Diff line change 11from dataclasses import dataclass
2- from urllib .parse import urlparse
2+ from urllib .parse import unquote , urlparse
33from typing import Dict , Mapping , Optional
44import os
55
@@ -58,6 +58,27 @@ def normalize_base_url(base_url: str) -> str:
5858 raise HyperbrowserError (
5959 "base_url must not include query parameters or fragments"
6060 )
61+
62+ decoded_base_path = parsed_base_url .path
63+ for _ in range (10 ):
64+ next_decoded_base_path = unquote (decoded_base_path )
65+ if next_decoded_base_path == decoded_base_path :
66+ break
67+ decoded_base_path = next_decoded_base_path
68+ if "\\ " in decoded_base_path :
69+ raise HyperbrowserError ("base_url must not contain backslashes" )
70+ if any (character .isspace () for character in decoded_base_path ):
71+ raise HyperbrowserError ("base_url must not contain whitespace characters" )
72+ if any (
73+ ord (character ) < 32 or ord (character ) == 127
74+ for character in decoded_base_path
75+ ):
76+ raise HyperbrowserError ("base_url must not contain control characters" )
77+ path_segments = [segment for segment in decoded_base_path .split ("/" ) if segment ]
78+ if any (segment in {"." , ".." } for segment in path_segments ):
79+ raise HyperbrowserError (
80+ "base_url path must not contain relative path segments"
81+ )
6182 return normalized_base_url
6283
6384 @classmethod
Original file line number Diff line number Diff line change @@ -226,6 +226,10 @@ def test_client_config_rejects_empty_or_invalid_base_url():
226226 HyperbrowserError , match = "base_url must not contain control characters"
227227 ):
228228 ClientConfig (api_key = "test-key" , base_url = "https://example.local\x00 api" )
229+ with pytest .raises (
230+ HyperbrowserError , match = "base_url path must not contain relative path segments"
231+ ):
232+ ClientConfig (api_key = "test-key" , base_url = "https://example.local/%2e%2e/api" )
229233
230234
231235def test_client_config_normalizes_headers_to_internal_copy ():
@@ -356,3 +360,15 @@ def test_client_config_normalize_base_url_validates_and_normalizes():
356360 HyperbrowserError , match = "base_url must not contain control characters"
357361 ):
358362 ClientConfig .normalize_base_url ("https://example.local\x00 api" )
363+ with pytest .raises (
364+ HyperbrowserError , match = "base_url path must not contain relative path segments"
365+ ):
366+ ClientConfig .normalize_base_url ("https://example.local/%252e%252e/api" )
367+ with pytest .raises (
368+ HyperbrowserError , match = "base_url must not contain backslashes"
369+ ):
370+ ClientConfig .normalize_base_url ("https://example.local/%255Capi" )
371+ with pytest .raises (
372+ HyperbrowserError , match = "base_url must not contain whitespace characters"
373+ ):
374+ ClientConfig .normalize_base_url ("https://example.local/%2520api" )
Original file line number Diff line number Diff line change @@ -122,6 +122,13 @@ def test_client_build_url_rejects_runtime_invalid_base_url_changes():
122122 ):
123123 client ._build_url ("/session" )
124124
125+ client .config .base_url = "https://example.local/%2e%2e/api"
126+ with pytest .raises (
127+ HyperbrowserError ,
128+ match = "base_url path must not contain relative path segments" ,
129+ ):
130+ client ._build_url ("/session" )
131+
125132 client .config .base_url = " "
126133 with pytest .raises (HyperbrowserError , match = "base_url must not be empty" ):
127134 client ._build_url ("/session" )
You can’t perform that action at this time.
0 commit comments