27 lines
806 B
Python
27 lines
806 B
Python
"""Security utilities for URL validation."""
|
|
|
|
import ipaddress
|
|
from urllib.parse import urlparse
|
|
|
|
|
|
def is_safe_url(url: str) -> bool:
|
|
"""Check if URL is safe (not pointing to private/internal networks)."""
|
|
try:
|
|
parsed = urlparse(url)
|
|
if parsed.scheme not in ("http", "https"):
|
|
return False
|
|
hostname = parsed.hostname
|
|
if not hostname:
|
|
return False
|
|
if hostname in ("localhost", "metadata.google.internal", "metadata.internal"):
|
|
return False
|
|
try:
|
|
ip = ipaddress.ip_address(hostname)
|
|
if ip.is_private or ip.is_loopback or ip.is_reserved or ip.is_link_local:
|
|
return False
|
|
except ValueError:
|
|
pass
|
|
return True
|
|
except Exception:
|
|
return False
|