Add SSRF mitigation for external camera URLs

Block access to cloud metadata services and dangerous destinations:
- AWS/GCP/Azure metadata endpoint (169.254.169.254)
- GCP internal metadata hostnames
- localhost and loopback addresses
- All link-local addresses (169.254.x.x)

Local network IPs (192.168.x.x, 10.x.x.x) are still allowed since
cameras are typically on the same LAN as the server.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
maziggy
2026-01-31 16:49:12 +01:00
co-authored by Claude Opus 4.5
parent 57e88044e9
commit 2960261aa9
+31 -4
View File
@@ -21,11 +21,14 @@ logger = logging.getLogger(__name__)
def _validate_camera_url(url: str, allowed_schemes: tuple[str, ...] = ("http", "https", "rtsp")) -> bool:
"""Validate camera URL format.
"""Validate camera URL format and block dangerous destinations.
This validates that the URL is well-formed, uses an allowed scheme,
and does not target cloud metadata services.
This validates that the URL is well-formed and uses an allowed scheme.
Note: This intentionally allows user-provided URLs as that is the
purpose of external camera configuration.
purpose of external camera configuration. Local network IPs are
allowed since cameras are typically on the same LAN.
Args:
url: URL to validate
@@ -38,7 +41,31 @@ def _validate_camera_url(url: str, allowed_schemes: tuple[str, ...] = ("http", "
parsed = urlparse(url)
if not parsed.scheme or not parsed.netloc:
return False
return parsed.scheme.lower() in allowed_schemes
if parsed.scheme.lower() not in allowed_schemes:
return False
# Block cloud metadata service endpoints (SSRF mitigation)
# These are dangerous destinations that should never be accessed
hostname = parsed.hostname or ""
blocked_hosts = (
"169.254.169.254", # AWS/GCP/Azure metadata
"metadata.google.internal", # GCP metadata
"metadata.google",
"localhost", # Block localhost to prevent internal service access
"127.0.0.1",
"::1",
"0.0.0.0",
)
if hostname.lower() in blocked_hosts:
logger.warning(f"Blocked camera URL targeting restricted host: {hostname}")
return False
# Block link-local addresses (169.254.x.x)
if hostname.startswith("169.254."):
logger.warning(f"Blocked camera URL targeting link-local address: {hostname}")
return False
return True
except Exception:
return False