From 2b0ed2296b6b40414da30d1ec4aceda4be0fa9af Mon Sep 17 00:00:00 2001 From: Georges-Antoine Assi Date: Wed, 27 May 2026 09:29:21 -0400 Subject: [PATCH] cleanup --- backend/utils/validation.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/backend/utils/validation.py b/backend/utils/validation.py index 56e9cbecb..108ace8fb 100644 --- a/backend/utils/validation.py +++ b/backend/utils/validation.py @@ -195,15 +195,13 @@ def validate_url_for_http_request(url: str, field_name: str = "URL") -> None: # Try to resolve hostname as IP address try: ip = ipaddress.ip_address(hostname) - if _is_forbidden_ip(ip): msg = f"Invalid {field_name}: private, internal, reserved, or multicast IP addresses are not allowed" log.error(f"SSRF prevention: {msg} - IP '{ip}'") raise ValidationError(msg, field_name) - # Literal IP — DNS resolution is not needed, allow it. + # DNS resolution is not needed, allow it return - except ValueError as e: # ipaddress.ip_address() only handles standard notation. HTTP clients # also accept hex integers (0x7f000001), decimal integers (2130706433), @@ -218,11 +216,11 @@ def validate_url_for_http_request(url: str, field_name: str = "URL") -> None: log.error(f"SSRF prevention: {msg} - IP '{ip}'") raise ValidationError(msg, field_name) - # Non-standard IPv4 literal — already validated above, allow it. + # Non-standard IPv4 literal return except OSError: - pass # Not an IP address at all - fall through to domain name checks + pass # Fall through to domain name checks # Additional checks for suspicious domain patterns hostname_lower = hostname.lower() @@ -251,6 +249,7 @@ def validate_url_for_http_request(url: str, field_name: str = "URL") -> None: resolved_ip = ipaddress.ip_address(sockaddr[0]) except ValueError: continue + if _is_forbidden_ip(resolved_ip): msg = ( f"Invalid {field_name}: hostname resolves to a private, "