Files
securelens-backend/app/utils/validators.py
2026-04-07 18:13:43 +05:30

47 lines
1.5 KiB
Python

import ipaddress
import socket
from urllib.parse import urlparse
from fastapi import HTTPException
PRIVATE_NETWORKS = [
ipaddress.ip_network("10.0.0.0/8"),
ipaddress.ip_network("172.16.0.0/12"),
ipaddress.ip_network("192.168.0.0/16"),
ipaddress.ip_network("127.0.0.0/8"),
ipaddress.ip_network("169.254.0.0/16"),
ipaddress.ip_network("0.0.0.0/8"),
ipaddress.ip_network("::1/128"),
ipaddress.ip_network("fc00::/7"),
ipaddress.ip_network("fe80::/10"),
]
def validate_url(url: str) -> str:
parsed = urlparse(url)
if parsed.scheme not in ("http", "https"):
raise HTTPException(status_code=400, detail="URL must use http or https scheme")
hostname = parsed.hostname
if not hostname:
raise HTTPException(status_code=400, detail="Invalid URL: no hostname found")
blocked_hostnames = {"localhost", "0.0.0.0"}
if hostname in blocked_hostnames:
raise HTTPException(status_code=400, detail="Scanning internal addresses is not allowed")
try:
resolved_ip = socket.gethostbyname(hostname)
ip = ipaddress.ip_address(resolved_ip)
for network in PRIVATE_NETWORKS:
if ip in network:
raise HTTPException(
status_code=400,
detail="Scanning internal/private IP addresses is not allowed",
)
except socket.gaierror:
raise HTTPException(status_code=400, detail=f"Could not resolve hostname: {hostname}")
return url