mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-06-23 05:05:24 -04:00
7e5db9a3c6
* fix(security): redact credential-bearing URLs and PII from logs Several log statements emitted sensitive data in clear text: - model_routes / chat_routes / contacts_routes logged endpoint URLs raw. Admin-configured URLs can embed credentials in userinfo or query (e.g. https://user:pass@host, ?api_key=...). Route them through a shared core.log_safety.redact_url() that drops userinfo/query/fragment. - note_routes / task_scheduler logged operator email addresses (smtp_user, recipient). Replaced with presence booleans, which keeps the diagnostic ("why didn't this send") without writing PII to logs. model_routes already had a local redactor on its HTTPStatusError branch; the generic except branch was missed, so reuse the existing helper there. Clears CodeQL py/clear-text-logging-sensitive-data alerts 264, 317, 324, 325, 343, 344, 528. * fix(security): re-bracket IPv6 hosts and single-source the URL redactor Address review on #4750: - redact_url now re-brackets IPv6 literals so host:port stays unambiguous (https://[2001:db8::1]:8443/v1, not the bracket-less ambiguous form). - point model_routes._redact_url_for_log at the shared helper so the two redactors are single-sourced (also picks up the IPv6 fix).
33 lines
1.0 KiB
Python
33 lines
1.0 KiB
Python
from core.log_safety import redact_url
|
|
|
|
|
|
def test_strips_userinfo():
|
|
assert redact_url("https://user:pass@host.example/v1/models") == "https://host.example/v1/models"
|
|
|
|
|
|
def test_strips_query_and_fragment():
|
|
assert redact_url("https://host.example/v1?api_key=secret#frag") == "https://host.example/v1"
|
|
|
|
|
|
def test_keeps_port_and_path():
|
|
assert redact_url("http://host.example:8080/api/tags") == "http://host.example:8080/api/tags"
|
|
|
|
|
|
def test_ipv6_host_keeps_brackets():
|
|
assert redact_url("https://user:pass@[2001:db8::1]:8443/v1") == "https://[2001:db8::1]:8443/v1"
|
|
assert redact_url("https://[2001:db8::1]/v1") == "https://[2001:db8::1]/v1"
|
|
|
|
|
|
def test_no_credentials_passthrough():
|
|
assert redact_url("https://host.example/v1/models") == "https://host.example/v1/models"
|
|
|
|
|
|
def test_empty_and_none():
|
|
assert redact_url("") == ""
|
|
assert redact_url(None) == ""
|
|
|
|
|
|
def test_garbage_does_not_raise():
|
|
# urlparse is lenient; just assert no credential-looking userinfo survives.
|
|
assert "@" not in redact_url("::::not a url::::")
|