fix(mavvrik): use urlparse.hostname to prevent userinfo bypass in domain validation

Replace netloc.split(":")[0] with urlparse().hostname in both
MavvrikInitRequest and MavvrikSettingsUpdate validators. The previous
approach was bypassable via URL userinfo (e.g.
https://api.mavvrik.dev:443@attacker.example/t) which would pass the
allowlist check while HTTP clients connect to the attacker host.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Praveen Ghuge 2026-05-13 22:31:06 +05:30
parent 5c10ef4ab8
commit ad62ce2b33

View file

@ -37,7 +37,7 @@ class MavvrikInitRequest(BaseModel):
def must_be_https_mavvrik_host(cls, v: str) -> str:
if not v.startswith("https://"):
raise ValueError("api_endpoint must be an HTTPS URL")
netloc = urlparse(v).netloc.split(":")[0] # strip port if present
netloc = (urlparse(v).hostname or "").lower() # strip userinfo/port
if not any(netloc.endswith(suffix) for suffix in _MAVVRIK_ALLOWED_SUFFIXES):
raise ValueError(
f"api_endpoint host must be a Mavvrik domain "
@ -152,7 +152,7 @@ class MavvrikSettingsUpdate(BaseModel):
return v
if not v.startswith("https://"):
raise ValueError("api_endpoint must be an HTTPS URL")
netloc = urlparse(v).netloc.split(":")[0]
netloc = (urlparse(v).hostname or "").lower() # strip userinfo/port
if not any(netloc.endswith(suffix) for suffix in _MAVVRIK_ALLOWED_SUFFIXES):
raise ValueError(
f"api_endpoint host must be a Mavvrik domain "