fix: block 0.0.0.0/8 in isPrivateIP to prevent loopback bypass

This commit is contained in:
2026-04-21 12:35:31 +02:00
parent 4ab30bcc1d
commit 6dc0001f9d
2 changed files with 2 additions and 0 deletions

View File

@@ -37,6 +37,7 @@ function isPrivateIP(string $ip): bool
if ($long === false) return true; if ($long === false) return true;
foreach ([ foreach ([
[ip2long('0.0.0.0'), 0xFF000000], // 0.0.0.0/8 unspecified (routes to loopback on Linux)
[ip2long('127.0.0.0'), 0xFF000000], // 127.0.0.0/8 loopback [ip2long('127.0.0.0'), 0xFF000000], // 127.0.0.0/8 loopback
[ip2long('10.0.0.0'), 0xFF000000], // 10.0.0.0/8 RFC1918 [ip2long('10.0.0.0'), 0xFF000000], // 10.0.0.0/8 RFC1918
[ip2long('172.16.0.0'), 0xFFF00000], // 172.16.0.0/12 RFC1918 [ip2long('172.16.0.0'), 0xFFF00000], // 172.16.0.0/12 RFC1918

View File

@@ -26,6 +26,7 @@ check(isPrivateIP('169.254.169.254'), 'AWS metadata IP');
check(!isPrivateIP('8.8.8.8'), 'Google DNS is public'); check(!isPrivateIP('8.8.8.8'), 'Google DNS is public');
check(!isPrivateIP('93.184.216.34'), 'example.com IP is public'); check(!isPrivateIP('93.184.216.34'), 'example.com IP is public');
check(isPrivateIP('not-an-ip'), 'unparseable IP blocked'); check(isPrivateIP('not-an-ip'), 'unparseable IP blocked');
check(isPrivateIP('0.0.0.0'), '0.0.0.0 blocked (routes to loopback)');
// --- getUserIP --- // --- getUserIP ---
unset($_SERVER['HTTP_CLIENT_IP']); unset($_SERVER['HTTP_CLIENT_IP']);