fix(scrapers): don't leak proxy creds in parse_proxy_url ValueError (#1945)
parse_proxy_url raised ValueError(f"...{proxy_url!r}") embedding the FULL proxy
URL incl. password. Это исключение всплывает в run_region_sweep try → пишется в
kn_scrape_runs.error (str(e)[:2000]) + log_progress + logger.exception→Sentry —
малформный proxy URL утёк бы пароль. Теперь сообщение содержит только scheme,
без сырого URL/creds. Happy-path лог уже server-only (host:port), creds не пишет.
test: ValueError-сообщение НЕ содержит пароль/юзера/сырой URL.
This commit is contained in:
parent
aafcb208e9
commit
906f89db98
2 changed files with 14 additions and 1 deletions
|
|
@ -57,7 +57,9 @@ def parse_proxy_url(proxy_url: str | None) -> dict[str, str] | None:
|
||||||
return None
|
return None
|
||||||
parts = urlsplit(proxy_url)
|
parts = urlsplit(proxy_url)
|
||||||
if not parts.hostname:
|
if not parts.hostname:
|
||||||
raise ValueError(f"proxy URL без host: {proxy_url!r}")
|
# НЕ эхо-им сырой proxy_url — он содержит пароль, а это исключение
|
||||||
|
# всплывает в kn_scrape_runs.error / log_progress / Sentry (#1945 sec-review).
|
||||||
|
raise ValueError(f"proxy URL без host (scheme={parts.scheme!r})")
|
||||||
scheme = parts.scheme or "http"
|
scheme = parts.scheme or "http"
|
||||||
server = f"{scheme}://{parts.hostname}"
|
server = f"{scheme}://{parts.hostname}"
|
||||||
if parts.port:
|
if parts.port:
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,17 @@ class TestParseProxyUrl:
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
parse_proxy_url("http://:8080")
|
parse_proxy_url("http://:8080")
|
||||||
|
|
||||||
|
def test_error_does_not_leak_credentials(self) -> None:
|
||||||
|
# ValueError всплывает в kn_scrape_runs.error / log_progress / Sentry —
|
||||||
|
# НЕ должен содержать пароль (#1945 sec-review).
|
||||||
|
bad = "http://secretuser:secretpass@:8080" # есть creds, но нет host
|
||||||
|
with pytest.raises(ValueError) as exc:
|
||||||
|
parse_proxy_url(bad)
|
||||||
|
msg = str(exc.value)
|
||||||
|
assert "secretpass" not in msg
|
||||||
|
assert "secretuser" not in msg
|
||||||
|
assert bad not in msg
|
||||||
|
|
||||||
|
|
||||||
class TestBrowserSessionThrottleThreading:
|
class TestBrowserSessionThrottleThreading:
|
||||||
"""concurrency/jitter/proxy прокидываются в инстанс-поля BrowserSession."""
|
"""concurrency/jitter/proxy прокидываются в инстанс-поля BrowserSession."""
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue