CVE-2026-6735

Cross-Site Scripting
Affects
PHP
in
PHP
No items found.
Versions
<8.2.31, >=8.3.0 <8.3.31, >=8.4.0 <8.4.21, >=8.5.0 <8.5.6

Patch Available.

Exclamation circle icon
Patch Available

This Vulnerability has been fixed in the Never-Ending Support (NES) version offered by HeroDevs.

Overview

PHP is a general-purpose scripting language used mostly for web development. It runs behind web servers through server APIs such as Apache mod_php and PHP-FPM, and powers content management systems and frameworks such as WordPress, Drupal, Moodle and Laravel. PHP-FPM (FastCGI Process Manager) runs PHP for web servers, and its optional status page, enabled with pm.status_path, shows the state of each worker in the pool, including the request it is serving.

A Cross-Site Scripting (XSS) vulnerability (CVE-2026-6735) has been identified in the full status page of PHP-FPM, which allows an attacker who can send a request to the pool to place markup in the request URI and so run script in the browser of whoever views the status page in HTML or XML format. PHP tracks this issue as GHSA-7qg2-v9fj-4mwv.

Per OWASP: Cross-Site Scripting (XSS) attacks occur when: Data enters a Web application through an untrusted source, most frequently a web request. The data is included in dynamic content that is sent to a web user without being validated for malicious content.

This issue affects PHP before 8.2.31, PHP 8.3 before 8.3.31, PHP 8.4 before 8.4.21 and PHP 8.5 before 8.5.6, which includes every End-of-Life release line from PHP 5.6 through 8.1, each through its final release.

Details

Module Info

Vulnerability Info

This High-severity vulnerability is found in the FPM SAPI of PHP before 8.2.31, 8.3 before 8.3.31, 8.4 before 8.4.21 and 8.5 before 8.5.6, including every End-of-Life release line from PHP 5.6 through 8.1, which never received the upstream fix. The PHP project scores it 7.3 under CVSS 4.0 (CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:H/VI:H/VA:N/SC:H/SI:H/SA:N/E:P/S:P/AU:Y/RE:L/U:Amber).

With ?full, the status page lists every worker of the pool with the method, URI and query string of the request it is serving or last served. In the HTML (?full&html) and XML (?full&xml) formats, PHP escaped the query string, although with flags that leave quotes alone, but inserted the request URI unchanged. In PHP 7.4.33 the code reads:

if (proc.query_string[0] != '\0') {
    if (!encode) {
        query_string = proc.query_string;
    } else {
        tmp_query_string = php_escape_html_entities_ex((unsigned char *)proc.query_string, strlen(proc.query_string), 1, ENT_HTML_IGNORE_ERRORS & ENT_COMPAT, NULL, 1);
        query_string = ZSTR_VAL(tmp_query_string);
    }
} 

The request URI is then passed to the page template as proc.request_uri with no escaping. An attacker who sends a request whose URI contains markup to any script in the pool gets that markup written into the status page while the request is recorded on the worker. When an administrator or a monitoring tool opens the full HTML or XML status page in a browser, the injected script runs with the origin of the status page, which is stored cross-site scripting. HeroDevs' analysis found the same unescaped output in the PHP 5.6, 7.2 and 7.4 lines.

Exploitation needs php-fpm with pm.status_path set and a victim who views the full status page in HTML or XML format in a browser. The attacker only needs to be able to send a request to the pool. Other SAPIs, FPM pools without a status path, and status pages viewed only in plain text are not affected. Upstream also escapes these fields in the JSON format. The NES release for PHP 5.6 does the same, while the NES releases for PHP 7.2 and 7.4 leave the JSON output unescaped, as those versions always produced it; a browser does not render that output as HTML.

The fix escapes the request URI as well as the query string, with flags that also encode quotes and characters not allowed in the document type:

if (encode_html) {
    tmp_request_uri_string = php_escape_html_entities_ex(
            (const unsigned char *) proc->request_uri,
            strlen(proc->request_uri), 1, ENT_DISALLOWED | ENT_HTML_DOC_XML1 | ENT_COMPAT,
            NULL, /* double_encode */ 1, /* quiet */ 0);
    request_uri_string = ZSTR_VAL(tmp_request_uri_string);
} 

Mitigation

The PHP project publishes security fixes only for its supported release lines. PHP 5.6, 7.0, 7.1, 7.2, 7.3, 7.4, 8.0 and 8.1 are End-of-Life and will not receive any public updates to address this issue.

Until an upgrade is possible, disable pm.status_path if the status page is not needed, restrict access to it to trusted monitoring hosts, or read it only in plain text format rather than in a browser.

Users of the affected components should apply one of the following mitigations:

  • Upgrade to PHP 8.2.31, 8.3.31, 8.4.21, 8.5.6, or later.
  • Leverage a commercial support partner like HeroDevs (NES for PHP) for post-EOL security support.

Credits

Vulnerability Details
Severity
Level
CVSS Assessment
Low
>=0 <4
Medium
>=4 <6
High
>=6 <8
Critical
>=8 <10
High
ID
CVE-2026-6735
PROJECT Affected
PHP
Versions Affected
<8.2.31, >=8.3.0 <8.3.31, >=8.4.0 <8.4.21, >=8.5.0 <8.5.6
NES Versions Affected
Published date
May 10, 2026
≈ Fix date
October 23, 2026
Fixed in
Category
Cross-Site Scripting
Vex Document
Download VEXHow do I use it?
Sign up for the latest vulnerability alerts fixed in
PHP
Rss feed icon
Subscribe via RSS
or

By submitting the form I acknowledge receipt of our Privacy Policy.

Thanks for signing up for our Newsletter! We look forward to connecting with you.
Oops! Something went wrong while submitting the form.