feat: CALDAV_ALLOWED_CIDRS Whitelist für interne CalDAV/Nextcloud-Server
Interne Nextcloud-Instanzen im LAN können jetzt per .env-Variable von der SSRF-Blockliste ausgenommen werden. Beispiel in .env: CALDAV_ALLOWED_CIDRS=192.168.1.0/24,10.10.5.50/32 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -33,6 +33,12 @@ class Settings(BaseSettings):
|
||||
first_superadmin_email: str = ""
|
||||
first_superadmin_password: str = ""
|
||||
|
||||
# CalDAV / outbound HTTP
|
||||
# Kommaseparierte CIDR-Whitelist für interne CalDAV-Server (z.B. Nextcloud im LAN).
|
||||
# Diese CIDRs sind vom SSRF-Schutz ausgenommen.
|
||||
# Beispiel: CALDAV_ALLOWED_CIDRS=192.168.1.0/24,10.10.5.50/32
|
||||
caldav_allowed_cidrs: list[str] = []
|
||||
|
||||
@model_validator(mode='after')
|
||||
def validate_secret_key(self):
|
||||
if self.app_env == 'production' and self.secret_key == 'change-me-in-production':
|
||||
|
||||
@@ -168,13 +168,38 @@ def _validate_caldav_url(url: str) -> None:
|
||||
raise ValueError(str(exc)) from exc
|
||||
|
||||
|
||||
def _get_allowed_networks() -> list[ipaddress.IPv4Network | ipaddress.IPv6Network]:
|
||||
"""Gibt die konfigurierten Whitelist-Netzwerke zurück (CALDAV_ALLOWED_CIDRS)."""
|
||||
from app.core.config import settings
|
||||
networks = []
|
||||
for cidr in settings.caldav_allowed_cidrs:
|
||||
cidr = cidr.strip()
|
||||
if not cidr:
|
||||
continue
|
||||
try:
|
||||
networks.append(ipaddress.ip_network(cidr, strict=False))
|
||||
except ValueError:
|
||||
log.warning("Ungültiger CIDR in CALDAV_ALLOWED_CIDRS ignoriert: %r", cidr)
|
||||
return networks
|
||||
|
||||
|
||||
def _check_ip_blocked(ip: ipaddress.IPv4Address | ipaddress.IPv6Address, hostname: str) -> None:
|
||||
"""Wirft ValueError wenn die IP in einem blockierten Netz liegt."""
|
||||
"""Wirft ValueError wenn die IP in einem blockierten Netz liegt.
|
||||
|
||||
Whitelist (CALDAV_ALLOWED_CIDRS) schlägt die Blockliste –
|
||||
damit können interne Nextcloud-Server im LAN trotzdem genutzt werden.
|
||||
"""
|
||||
# Whitelist-Check zuerst: explizit erlaubte CIDRs überschreiben die Blockliste
|
||||
for allowed in _get_allowed_networks():
|
||||
if ip in allowed:
|
||||
return # explizit erlaubt → kein Fehler
|
||||
|
||||
for network in _BLOCKED_NETWORKS:
|
||||
if ip in network:
|
||||
raise ValueError(
|
||||
f"Host '{hostname}' ({ip}) liegt in einem privaten/reservierten "
|
||||
f"Adressbereich ({network}) und darf nicht als CalDAV-Server genutzt werden."
|
||||
f"Adressbereich ({network}) und darf nicht als CalDAV-Server genutzt werden. "
|
||||
f"Tipp: Interne Server können per CALDAV_ALLOWED_CIDRS freigegeben werden."
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user