Fix GHSA-62xp-839h-2637: FastCGI allowed_clients compared only 96 bits of IPv6 addresses

This commit is contained in:
Alexandre Daubois authored and Jakub Zelenka committed 2026-09-18 17:06:17 +02:00
1 parent b4e3397ec8
commit dcdfcf86fc
3 files changed
+105 -1

No files matched your search

+1 -1
View File
@@ -1340,7 +1340,7 @@ static int fcgi_is_allowed(void) {
if (client_sa.sa.sa_family == AF_INET6) {
for (i = 0; allowed_clients[i].sa.sa_family ; i++) {
if (allowed_clients[i].sa.sa_family == AF_INET6
&& !memcmp(&client_sa.sa_inet6.sin6_addr, &allowed_clients[i].sa_inet6.sin6_addr, 12)) {
&& !memcmp(&client_sa.sa_inet6.sin6_addr, &allowed_clients[i].sa_inet6.sin6_addr, sizeof(client_sa.sa_inet6.sin6_addr))) {
return 1;
}
#ifdef IN6_IS_ADDR_V4MAPPED
@@ -0,0 +1,52 @@
--TEST--
GHSA-62xp-839h-2637: IPv6 allowed client compared on all 128 bits
--SKIPIF--
<?php
include "skipif.inc";
FPM\Tester::skipIfIPv6IsNotSupported();
?>
--FILE--
<?php
require_once "tester.inc";
$cfg = <<<EOT
[global]
error_log = {{FILE:LOG}}
[exact]
listen = {{ADDR:IPv6:ANY[exact]}}
listen.allowed_clients = ::1
pm = static
pm.max_children = 1
[prefix]
listen = {{ADDR:IPv6:ANY[prefix]}}
listen.allowed_clients = ::dead:beef
pm = static
pm.max_children = 1
catch_workers_output = yes
EOT;
$tester = new FPM\Tester($cfg);
$tester->start();
$tester->expectLogStartNotices();
$tester->checkRequest('{{ADDR:IPv6[exact]}}', 'exact: ok', 'exact: error');
$tester->checkRequest('{{ADDR:IPv6[prefix]}}', 'prefix: ok', 'prefix: error');
$tester->terminate();
$tester->expectLogWarning(
'child %d said into stderr: "ERROR: Connection disallowed: IP address \'::1\' has been dropped."',
'prefix'
);
$tester->expectLogTerminatingNotices();
$tester->close();
?>
Done
--EXPECT--
exact: ok
prefix: error
Done
--CLEAN--
<?php
require_once "tester.inc";
FPM\Tester::clean();
?>
@@ -0,0 +1,52 @@
--TEST--
GHSA-62xp-839h-2637: IPv4-mapped allowed client compared on all 128 bits
--SKIPIF--
<?php
include "skipif.inc";
FPM\Tester::skipIfIPv6IsNotSupported();
?>
--FILE--
<?php
require_once "tester.inc";
$cfg = <<<EOT
[global]
error_log = {{FILE:LOG}}
[exact]
listen = {{ADDR:IPv6:ANY[exact]}}
listen.allowed_clients = ::ffff:127.0.0.1
pm = static
pm.max_children = 1
[prefix]
listen = {{ADDR:IPv6:ANY[prefix]}}
listen.allowed_clients = ::ffff:203.0.113.1
pm = static
pm.max_children = 1
catch_workers_output = yes
EOT;
$tester = new FPM\Tester($cfg);
$tester->start();
$tester->expectLogStartNotices();
$tester->checkRequest('{{ADDR:IPv4[exact]}}', 'exact: ok', 'exact: error');
$tester->checkRequest('{{ADDR:IPv4[prefix]}}', 'prefix: ok', 'prefix: error');
$tester->terminate();
$tester->expectLogWarning(
'child %d said into stderr: "ERROR: Connection disallowed: IP address \'127.0.0.1\' has been dropped."',
'prefix'
);
$tester->expectLogTerminatingNotices();
$tester->close();
?>
Done
--EXPECT--
exact: ok
prefix: error
Done
--CLEAN--
<?php
require_once "tester.inc";
FPM\Tester::clean();
?>