From dc85f33e9f63db6f477b5654ecefc38c352b6d0f Mon Sep 17 00:00:00 2001 From: Moirtz Wagner Date: Fri, 28 Aug 2026 16:14:25 +0200 Subject: [PATCH] ipInNetwork(): Praefixlaenge pruefen statt ungeprueft uebernehmen Die Laenge wurde mit intval() aus dem CIDR-String uebernommen. Bei einem Tippfehler in LOCAL_NETWORKS lief die Funktion damit fail-open: "/-5" ergibt intdiv(-5,8)=0 ganze Bytes und chr((0xFF << 13) & 0xFF)=Nullbyte, womit beide maskierten Bytes gleich sind und jede Adresse in jedem Netz liegt. isLocal() haette dann jede Anfrage aus dem Internet als lokal gewertet - und damit als angemeldet, inklusive Freigabe der Passkey-Registrierung. Die Laenge muss jetzt aus reinen Ziffern bestehen und darf die Adressbreite nicht ueberschreiten; sonst liefert die Funktion false. "/-5", "/244", "/abc" und "/" fallen damit durch, gueltige Angaben bleiben unveraendert. Co-Authored-By: Claude Opus 5 --- helper.php | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/helper.php b/helper.php index 0597058..485af29 100644 --- a/helper.php +++ b/helper.php @@ -20,7 +20,20 @@ function ipInNetwork($ip, $cidr) if ($adresse === false || $netz === false || strlen($adresse) !== strlen($netz)) { return false; // ungueltig oder verschiedene Adressfamilien } - $bits = isset($teile[1]) ? intval($teile[1]) : strlen($adresse) * 8; + // Praefixlaenge streng pruefen. Ohne das macht ein Tippfehler in + // LOCAL_NETWORKS die Funktion fail-open: "/-5" etwa liefert eine + // Nullmaske, und dann liegt jede Adresse in jedem Netz. + if (isset($teile[1])) { + if (!ctype_digit($teile[1])) { + return false; + } + $bits = intval($teile[1]); + if ($bits > strlen($adresse) * 8) { + return false; + } + } else { + $bits = strlen($adresse) * 8; + } $ganzeBytes = intdiv($bits, 8); $restBits = $bits % 8; if ($ganzeBytes > 0 && strncmp($adresse, $netz, $ganzeBytes) !== 0) {