import ipaddress import socket from urllib.parse import urlparse def safe_public_url(url): """Resolve url's host and reject any that maps to a non-public IP (SSRF guard).""" p = urlparse(url) if p.scheme not in ("http", "https") or not p.hostname: raise ValueError("url must be http(s) with a hostname") for info in socket.getaddrinfo(p.hostname, None): ip = ipaddress.ip_address(info[4][0]) if (ip.is_private or ip.is_loopback or ip.is_link_local or ip.is_reserved or ip.is_multicast or ip.is_unspecified): raise ValueError(f"host resolves to non-public ip {ip}") return url