← Back to Feed CACHED · 2026-05-17 09:42:19 · cache_key CVE-2025-29912
CVE-2026-6735 · CWE-79 · Disclosed 2026-05-10

In PHP versions 8

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
01 · The Real Story

Like graffiti on a maintenance hatch that only matters if an admin opens it from the wrong side

CVE-2026-6735 is an XSS bug in the PHP-FPM status endpoint, not in ordinary PHP page rendering. Upstream affected ranges are PHP 8.2.x before 8.2.31, 8.3.x before 8.3.31, 8.4.x before 8.4.21, and 8.5.x before 8.5.6; the vulnerable behavior is that attacker-controlled request data can be reflected into the status page, where it executes if someone views the HTML status output in a browser.

The vendor's MEDIUM 6.1 is defensible in a lab, but a little generous in real enterprise conditions. The chain needs pm.status_path enabled, the status page reachable, a victim to open the HTML view, and some same-origin value to steal or abuse; that is a long way from pre-auth RCE, and most mature shops already keep this page internal-only or disabled.

"This is a niche operator-side XSS in PHP-FPM status, not an internet-scale PHP takeover bug."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Find a reachable PHP-FPM status page

An attacker starts with recon using common web tooling such as httpx, nuclei, or plain curl against paths like /fpm-status or custom pm.status_path values. The goal is not PHP code execution; it is simply locating a status endpoint that the web server exposes to a browser.
Conditions required:
  • php-fpm is deployed
  • pm.status_path is enabled in at least one pool
  • the web server routes requests to that status path
  • the attacker can reach the endpoint from their network position
Where this breaks in practice:
  • The PHP manual explicitly recommends restricting the page to internal requests or known IPs
  • many deployments proxy the status page only via localhost or a Unix domain socket-backed local route
  • custom path names reduce commodity scanning success
Detection/coverage: Exposure scanners can find the path, but most version scanners only report package versions. Web logs and reverse-proxy logs will usually show probing for /fpm-status, /status, or ?full.
STEP 02

Seed a malicious request URI

Using Burp Suite or curl, the attacker sends a crafted HTTP request whose URL contains a JavaScript payload. Because the bug is improper sanitization of user data in the status output, that request can become the bait an operator later renders in the status page.
Conditions required:
  • the attacker can send at least one HTTP request through the same PHP-FPM pool
  • the vulnerable branch is running
  • the request metadata is surfaced in the status page view
Where this breaks in practice:
  • if the request hits a different pool than the monitored one, the payload may never appear
  • if the status page is viewed in text, JSON, XML, or OpenMetrics workflows, the browser-execution angle disappears
  • URL normalization or upstream filtering may mangle simple payloads
Detection/coverage: Look for encoded <script>, event-handler strings, or suspicious URI characters in web access logs and reverse-proxy telemetry.
STEP 03

Wait for a human to open the HTML status view

The exploit only pays off when an operator, admin, or developer opens the status page in a browser, especially the HTML rendering such as /fpm-status?html&full. This is classic browser-side execution: no human view, no exploit outcome.
Conditions required:
  • a human with browser access views the status page
  • the page is rendered as HTML
  • the victim browser can execute the injected payload
Where this breaks in practice:
  • many monitoring stacks consume machine-readable output rather than HTML
  • admins may rarely open the status page interactively
  • some teams segregate monitoring on a separate host or origin, limiting useful browser context
Detection/coverage: Proxy logs, browser telemetry, and SOC web-history enrichment can show interactive access to the status page around the same time as the malicious request.
STEP 04

Abuse the browser session on that origin

Once the JavaScript runs, the attacker can try same-origin actions such as reading page content, making authenticated requests, or stealing tokens/cookies that are scoped to that origin. Tooling could be as simple as handcrafted JS or a browser-hook framework like BeEF, but the impact stays bounded by the browser session and origin policy.
Conditions required:
  • the victim session has something valuable in that origin context
  • cookies are readable or actions are CSRF-able from the page origin
  • the endpoint shares an origin with something sensitive
Where this breaks in practice:
  • this is not server-side execution
  • if the status endpoint is on a separate vhost or internal-only hostname, cookie and application blast radius shrinks hard
  • HttpOnly cookies and tight CSP can reduce post-XSS value
Detection/coverage: Browser security tooling, CSP violation reporting, and unusual same-origin follow-on requests from an admin workstation are your best signals; server EDR will not reliably catch the browser-stage abuse.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo authoritative evidence of active exploitation located in vendor, NVD, or CISA KEV sources. This aligns with the supplied EPSS 0.00046 and the absence of KEV listing.
Proof-of-concept availabilityNo authoritative public PoC was validated from upstream PHP or GitHub advisory material. The public patch trail is enough for a competent researcher to reproduce, but this is not currently a commodity exploit story.
EPSS0.00046 from the provided intel block; that is extremely low exploitation probability pressure compared with bugs that move patch queues.
KEV statusNot listed in CISA's Known Exploited Vulnerabilities catalog.
CVSS vector reality checkCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N correctly captures UI:R and no server-side availability impact. In practice, the real penalty is even harsher because reachability depends on an intentionally enabled monitoring endpoint.
Affected versionsUpstream branches affected: 8.2.x < 8.2.31, 8.3.x < 8.3.31, 8.4.x < 8.4.21, 8.5.x < 8.5.6.
Fixed versionsUpstream fixed in PHP 8.2.31, 8.3.31, 8.4.21, and 8.5.6, released on 2026-05-07.
Distro backportsDo not key only on upstream version strings in distro environments. Ubuntu shipped fixes via package backports in USN-8336-1 and Debian LTS addressed the issue in php7.4 7.4.33-1+deb11u11, even though those versions do not look like upstream 8.x.
Exposure populationNo reliable internet-scale census for this exact path was found. My assessment is low exposed population by design because PHP's own manual says the status page should be restricted to internal requests or known client IPs; that is an inference from official deployment guidance, not a measured internet-wide count.
Disclosure and attributionNVD shows published 2026-05-10 with PHP Group as source. Upstream changelog and NVD do not clearly credit an external reporting researcher.
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to LOW (3.8/10)

The decisive factor is reachability friction: this bug only matters if a deliberately enabled PHP-FPM status page is exposed to a browser-accessible user path. Even then, the impact is browser-bound XSS on a monitoring endpoint, not server compromise, and there is no current exploitation pressure pushing it up the queue.

HIGH Exploit chain requires a human to view the HTML status page
HIGH This is not a direct server-side code execution path
MEDIUM Real exposed population is probably small, but not directly census-verified

Why this verdict

  • Start from the vendor 6.1 baseline, then subtract for endpoint exposure: exploitation begins only if pm.status_path is enabled and reachable; plenty of fleets never expose that path beyond localhost or monitoring IPs.
  • Subtract again for attacker workflow friction: the bug needs an operator to open the HTML status page in a browser. JSON, XML, text, and OpenMetrics consumers do not turn this into active script execution.
  • Subtract for blast radius: this is XSS in a status/monitoring surface, so the payoff is limited to the victim browser's same-origin context rather than arbitrary server execution or tenant-wide takeover.
  • Keep it above IGNORE because the chain is still real: if you expose /fpm-status on the same origin as sensitive apps, a crafted URI plus an admin browser session can become useful session abuse.
  • No threat pressure amplifier: supplied intel says EPSS 0.00046 and not KEV-listed, with no validated active exploitation evidence.

Why not higher?

It is not higher because this is not a one-packet internet RCE, auth bypass, or wormable edge bug. The exploit path assumes an exposed diagnostics page, a human viewing the HTML page, and enough same-origin value to make the XSS worthwhile.

Why not lower?

It is not lower because many teams do expose FPM status for troubleshooting, and some do it on the same hostname as production apps. If that operational shortcut exists, this bug can absolutely turn into session theft or authenticated action abuse against the victim browser context.

05 · Compensating Control

What to do — in priority order.

  1. Restrict the status page to localhost or monitoring IPs — Apply web-server ACLs or reverse-proxy allowlists in normal change control. For a LOW verdict there is no SLA (treat as backlog hygiene), but this is the single best compensating control because it kills the browser-accessible prerequisite entirely.
  2. Disable pm.status_path where it is not operationally required — Remove or comment the directive in unused pools, then reload PHP-FPM during the next routine maintenance cycle. This is the cleanest way to eliminate exposure without waiting on package rollout.
  3. Serve status on a separate internal-only origin — If operations truly need the page, move it behind a distinct hostname or management vhost not sharing cookies with production applications. For LOW, do this as backlog hygiene rather than emergency response.
  4. Add a restrictive CSP on the status endpoint — Set a web-server header such as Content-Security-Policy: default-src 'none'; style-src 'self' 'unsafe-inline' if your status view still needs HTML. CSP is not perfect, but it reduces post-injection payoff and should be deployed in the next normal config update.
What doesn't work
  • Generic server EDR does not stop browser-side JavaScript running in an admin's browser.
  • MFA does not meaningfully help once malicious script executes inside an already-authenticated browser session on the same origin.
  • A WAF alone is unreliable here because the payload can be encoded in request URIs and the vulnerable reflection is inside a diagnostics page, not a standard application route.
06 · Verification

Crowdsourced verification payload.

Run this on the target Linux host that serves PHP-FPM, not from an auditor workstation. Invoke it as sudo bash ./check-cve-2026-6735.sh; it needs read access to PHP-FPM binaries and pool config directories, so root or equivalent read privileges are recommended. The script is upstream-version aware and treats distro-backported packages conservatively as UNKNOWN when versioning is ambiguous.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# check-cve-2026-6735.sh
# Detect likely exposure to CVE-2026-6735 (PHP-FPM status endpoint XSS)
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN

set -u

say() { echo "$1"; }

have_cmd() { command -v "$1" >/dev/null 2>&1; }

ver_lt() {
  # returns 0 if $1 < $2
  [ "$(printf '%s\n%s\n' "$1" "$2" | sort -V | head -n1)" != "$2" ]
}

find_php_fpm_bin() {
  local c
  for c in php-fpm php-fpm8.5 php-fpm8.4 php-fpm8.3 php-fpm8.2 php-fpm8.1 php-fpm8.0 php-fpm7.4; do
    if have_cmd "$c"; then
      echo "$c"
      return 0
    fi
  done
  return 1
}

get_php_fpm_version() {
  local bin="$1"
  "$bin" -v 2>/dev/null | awk '/^PHP / {print $2; exit}'
}

branch_fixed_version() {
  case "$1" in
    8.2) echo "8.2.31" ;;
    8.3) echo "8.3.31" ;;
    8.4) echo "8.4.21" ;;
    8.5) echo "8.5.6" ;;
    *) echo "" ;;
  esac
}

status_path_enabled() {
  local found=1
  local dirs=(
    /etc/php-fpm.d
    /etc/php/*/fpm/pool.d
    /usr/local/etc/php-fpm.d
    /usr/local/etc/php-fpm.d/*.conf
    /opt/remi/php*/root/etc/php-fpm.d
  )

  # shellcheck disable=SC2086
  grep -R -n -E '^[[:space:]]*pm\.status_path[[:space:]]*=' ${dirs[@]} 2>/dev/null | grep -v '^[[:space:]]*#' >/dev/null 2>&1
  found=$?
  return $found
}

BIN="$(find_php_fpm_bin || true)"
if [ -z "${BIN:-}" ]; then
  say "UNKNOWN: php-fpm binary not found"
  exit 2
fi

VER="$(get_php_fpm_version "$BIN")"
if [ -z "${VER:-}" ]; then
  say "UNKNOWN: unable to determine PHP-FPM version from $BIN"
  exit 2
fi

BRANCH="$(echo "$VER" | awk -F. '{print $1"."$2}')"
FIXED="$(branch_fixed_version "$BRANCH")"

if [ -z "$FIXED" ]; then
  say "UNKNOWN: PHP-FPM version $VER is outside upstream affected branches or may rely on distro backports"
  exit 2
fi

if ! status_path_enabled; then
  if ver_lt "$VER" "$FIXED"; then
    say "UNKNOWN: vulnerable upstream version $VER detected, but no enabled pm.status_path found in common config locations"
    exit 2
  else
    say "PATCHED: version $VER is at or above fixed upstream level $FIXED and no enabled status path was found"
    exit 0
  fi
fi

if ver_lt "$VER" "$FIXED"; then
  say "VULNERABLE: php-fpm version $VER is below fixed version $FIXED and pm.status_path appears enabled"
  exit 1
fi

say "PATCHED: php-fpm version $VER is at or above fixed version $FIXED; pm.status_path may be enabled, but upstream fix is present"
exit 0
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning, have your web-platform owners inventory every host and container running PHP-FPM with pm.status_path enabled, then strip external access or disable the endpoint where it is not needed. Under the noisgate mitigation SLA there is no SLA for LOW — treat this as backlog hygiene, not an emergency — and under the noisgate remediation SLA it is also backlog hygiene, so fold upgrades to 8.2.31 / 8.3.31 / 8.4.21 / 8.5.6 or distro backports into the next routine web-stack maintenance cycle while immediately fixing any accidentally internet-reachable status pages you discover.

Sources

  1. NVD CVE-2026-6735
  2. PHP 8 ChangeLog
  3. PHP manual: FPM status page
  4. CISA Known Exploited Vulnerabilities Catalog
  5. Ubuntu USN-8336-1: PHP vulnerabilities
  6. Debian LTS DLA-4586-1: php7.4 security update
  7. Tenable CVE plugin coverage
  8. PHP.Watch 8.2.31 release notes
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.