IPv6 ACL bypass in FastCGI listen.allowed_clients due to partial address comparison (memcmp 12 bytes)

Kurzinfo

Metadaten

  • Original (extern): Link oeffnen
  • Veroeffentlicht: 2026-09-24 10:06 UTC
  • Importiert: 2026-10-07 06:38 UTC
  • CVSS: 6.5
  • Quelle-ID: php_sec
  • uid_hash: f10ebf60409dea701a417ea94c932d900f56230836361d720084dcb6b2b9914e

Inhalt

Summary

The IPv6 branch of the FastCGI client access check compares only the first 12 bytes of a 16-byte IPv6 address, so listen.allowed_clients matches on a /96 prefix instead of the exact address. An attacker who can source an address sharing the first 96 bits with an allowed one passes the check and reaches the FastCGI endpoint.

Details

fcgi_is_allowed() in main/fastcgi.c compares IPv6 client addresses with a hard-coded length of 12:

https://github.com/php/php-src/blob/php-8.5.10/main/fastcgi.c#L1334

An exact IPv6 comparison must cover all 16 bytes of struct in6_addr. The IPv4 branch above it compares its full 4 bytes correctly, and the IN6_IS_ADDR_V4MAPPED branch legitimately uses a 12-byte offset to reach the embedded IPv4 address, but that offset is not a valid length for a plain IPv6 comparison. Allowed addresses are parsed as full addresses with inet_pton(AF_INET6, ...), so the truncated comparison silently widens every configured entry to a /96 network.

The fix compares sizeof(client_sa.sa_inet6.sin6_addr) bytes.

PoC

Tested against a real php-fpm (fpm-fcgi), not a mock.

  1. Configure a pool:
listen = [::1]:19091
listen.allowed_clients = ::2
  1. Run php-fpm and send a FastCGI request from ::1 to [::1]:19091 for a test script.

  2. The request is accepted and the script executes, even though ::1 is not in listen.allowed_clients. Both addresses share the first 96 bits.

  3. Control test: set listen.allowed_clients = 2001:db8::2 and send the same request from ::1. The connection is denied as expected, because the first 96 bits differ.

Impact

This is an access control bypass in deployments that use FastCGI over IPv6 TCP and rely on listen.allowed_clients as a security boundary. An attacker with network reachability who can source an address within the same /96 as an allowed client bypasses the ACL and reaches the FastCGI endpoint, which in many deployments means executing PHP scripts in the FPM worker context.

Deployments using Unix sockets, IPv4 only, or an external firewall as the actual boundary are not affected.

Credit

This issue was originally reported in GHSA-r37j-mv37-rjpc. That advisory could not be used because the reporting account was deleted.

Verknuepfte CVEs

CVE-ID Severity (Quelle) CVSS (Quelle) Severity (CVE.org) CVSS (CVE.org) EPSS EPSS-Pctl Veroeffentlicht (CVE.org)

CVE-2026-91768

MEDIUM

6.5

MEDIUM

6.5

2026-09-25

Quellen-Details

Bezeichnung Name Kategorie Tags Zielgruppe Sprache Feed-URL
PHP Security (php/php-src GHSA)

php_sec

vendor_advisory php, runtime - de https://github.com/php/php-src/security/advisories