CVE-2026-87902 WordPress: Unauthenticated Path Traversal Leading to Conditional RCE - Safe Security

CVE-2026-87902 WordPress: Unauthenticated Path Traversal Leading to Conditional RCE

Oct 7, 2026 8 minute read

1. Introduction

CVE-2026-87902 is an unauthenticated path traversal vulnerability in WordPress page-template resolution. Under specific theme and server conditions, a remote attacker can include a readable local PHP file outside the active theme directories. A suitable include target can turn this into remote code execution (RCE).

The vulnerability has a CVSS v4.0 score of 9.2 (Critical). This article examines the vulnerable code path and a controlled comparison of WordPress 7.1.1 and 7.1.2, including HTTP-visible command execution as the web server account.

Robert Ressl discovered and responsibly disclosed the vulnerability. WordPress released 7.1.2 on September 22, 2026, with security backports for branches through 4.7. CISA added the CVE to its Known Exploited Vulnerabilities catalog on September 25, 2026.

2. WordPress Description

WordPress is an open-source content management system developed by a global contributor community. Its template hierarchy selects the PHP file used to render a requested page. The get_page_template() function builds candidates from the saved custom template, page name, page ID, and generic page.php. Template resolution finds a matching file, and the template loader includes it. The vulnerability lets a request-derived candidate escape the intended theme directory.

3. Vulnerability Severity

CVE ID CVE-2026-87902 (WordPress Core)
Severity CRITICAL
CVSS v4.0 Score 9.2 / 10
CVSS v4.0 Vector CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
CVSS v3.1 Score 8.1 / 10 (High, CISA ADP)
CVSS v3.1 Vector CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
CWE CWE-98 – Improper Control of Filename for Include/Require Statement
GitHub Advisory GHSA-7hp8-65ch-5whp
Fixed Versions 7.1.2, 7.0.6, 6.9.9, 6.8.10, 6.7.9, 6.6.9, 6.5.12, 6.4.12, 6.3.12, 6.2.13, 6.1.14, 6.0.16, 5.9.18, 5.8.17, 5.7.19, 5.6.21, 5.5.22, 5.4.23, 5.3.25, 5.2.28, 5.1.26, 5.0.29, 4.9.33, 4.8.32, 4.7.37

The vendor rates the vulnerability Critical under CVSS v4.0. CISA’s separate CVSS v3.1 assessment is 8.1 (High). The v4.0 AT:P metric reflects required deployment conditions; the score does not mean every WordPress installation is exploitable. Code execution depends on the active theme, available local PHP files, and runtime configuration.

4. Scope of Impact

  • Affected releases: Unpatched versions on WordPress branches 4.7 through 7.1. For example, branch 7.1 is affected through 7.1.1 and branch 4.7 through 4.7.36. The fixed releases listed above are excluded.
  • Tested versions: WordPress 7.1.1 (vulnerable) and 7.1.2 (patched).
  • Theme requirement: The active child or parent theme has a top-level directory whose name begins with page-, such as page-templates.
  • Include requirement: The selected local .php file exists and is readable by the web server account. The tested request path also uses a valid page_id.
  • RCE requirement: The included PHP file must enable an execution chain. The demonstrated PEAR chain requires a readable pearcmd.php and register_argc_argv enabled.
  • Fixed releases: WordPress 7.1.2 and the branch-specific backports listed in the severity table, released September 22, 2026.

Assess both the installed WordPress version and the deployment prerequisites. PHP inclusion runs the selected file in the application context; it does not automatically reveal that file’s source code. Any disclosed output depends on what the included file does.

5. Where is the vulnerability present?

The vulnerability is present in get_page_template() in wp-includes/template.php. When WordPress renders a page, the function builds the candidate-template list, and one family of candidates is derived directly from the request’s pagename query variable:

CVE-2026-87902 Best CTEM Platform, CTEM

The saved custom template is checked with validate_file(). In the vulnerable release, the decoded pagename candidate is added without the same validation. This allows encoded traversal to reach template resolution.

The candidate has a page- prefix and a .php suffix. A traversal therefore needs an existing page-prefixed directory in the active theme before it can move outside that directory. The appended extension constrains the chosen target to a PHP filename.

WordPress sanitizes the page name before building the candidate, but preserves percent-encoded octets. The later urldecode() call can restore traversal characters. The recorded requests use double encoding and a valid page_id to reach the page-template path.

locate_template() can resolve the resulting candidate outside the theme; the template loader then includes the selected file. The decoded page-name candidate was introduced in WordPress 4.7, which is the oldest branch covered by this advisory.

WordPress 7.1.2 adds validate_file() to the decoded pagename condition. It also checks candidates found by locate_template() with _wp_is_template_path_allowed(). Paths without a matching parent-directory traversal segment pass this helper directly.

For paths requiring the additional check, the helper resolves the real path and compares it with allowed directories: the stylesheet directory, template directory, and theme-compat. It also permits the direct parent directory for themes installed in a subdirectory. This is a traversal containment check, not a universal realpath restriction on every template.

6. Risk

The inclusion can execute existing PHP code outside the theme and return any output it produces. In the lab, the response from a page URL contains the OPML header generated by wp-links-opml.php. This supports local file inclusion; it does not demonstrate PHP source disclosure or retrieval of private records.

The demonstrated escalation uses the existing PEAR utility with query-string arguments available through register_argc_argv. Its file-writing behavior creates a PHP-bearing file in a location writable by the web server account. A subsequent inclusion returns command output. The impact is bounded by that account’s permissions and the container configuration.

Patchstack reports initial probing at 11:49 UTC on September 22, 2026, and a first PEAR file-write attempt at 15:34 UTC that day. Its September 23 update describes broader scanning and attempts to write PHP files. These observations establish exploitation activity, but individual requests or scanner user agents do not establish successful compromise.

Successful code execution can expose application secrets and data accessible to the web server account, permit unauthorized changes, or disrupt service. Review sites that met the prerequisites during their exposure window. Determine compromise from correlated request, response, process, and filesystem evidence.

7. Mitigation

  • Upgrade to WordPress 7.1.2 or the patched release on your branch. Prefer a current supported release, since older backports address this flaw without providing the same ongoing support.
  • As an interim measure, reject traversal in pagename, including encoded variants in query strings and POST bodies. Test the rule against legitimate traffic. Filtering does not replace patching.
  • Where compatible, disable register_argc_argv for web PHP. This breaks the tested PEAR chain, but leaves the inclusion flaw and other potential include targets.
  • Check the active child and parent themes for a top-level page- directory. If you cannot update promptly, assess a compatible theme change with its maintainer.
  • Search request logs for encoded traversal in pagename, unexpected pairing with page_id, and PEAR references. User agents can be spoofed, and standard logs may omit POST bodies; use WAF or application telemetry where available.
  • Investigate unexpected PHP files in web-server-writable locations such as /tmp and /var/tmp. Correlate content, ownership, timestamps, and requests before concluding compromise.

8. Exploit Implementation

Attack Scenario

The September 29 run compared WordPress 7.1.1 and 7.1.2 in the existing isolated Docker lab. Both used the same classic lab theme with a top-level page-templates directory and a published page with ID 4. The PHP runtime reported register_argc_argv enabled, and pearcmd.php was present at /usr/local/lib/php/pearcmd.php. The attacker container sent requests over the internal network.

The prior session’s /tmp/pwned87902.php was removed from the containers before the new absent-file check. The following sequence records the before state, the vulnerable include and PEAR write, command output, and the patched responses.

Prerequisites:

Docker and Docker Compose

WordPress 7.1.1 and 7.1.2 with the same theme and PHP settings

A readable pearcmd.php, register_argc_argv enabled, and a valid published page ID

An internal attacker container and a writable /tmp directory for the tested chain

Exploitation

1. Confirm the versions, PHP and theme prerequisites, and container state.

CVE-2026-87902 , CTEM

2. Check that the target file is absent, then traverse to an existing WordPress PHP file through page-template resolution.

CVE-2026-87902 , Best CTEM Platform

CVE-2026-87902 Best CTEM Platform

Figure 1: The file is absent before exploitation. The page URL then returns the OPML header from wp-links-opml.php. Only the first nine response lines are shown.

3. Include PEAR’s utility through the same path to write /tmp/pwned87902.php.

CVE-2026-87902, Best CTEM Platform

CVE-2026-87902 CTEM

Figure 2: The PEAR utility reports creating the target PHP file. The subsequent HTTP output and file listing provide independent evidence of the write and execution.

4. Include the newly written file from an unauthenticated page URL and check its on-disk result.

CVE-2026-87902 CTEM

CVE-2026-87902 Best CTEM Platform

Figure 3: The HTTP response contains the output of id as www-data, and the file listing records the written PHP file. This supports command execution in the vulnerable container.

5. Repeat both requests against WordPress 7.1.2. In a later September 29 follow-up, save each complete HTTP response and check the file state.

CVE-2026-87902 Best CTEM Platform CVE-2026-87902

Figure 4: The later patched write request saved a complete 20,756-byte response. It returned HTTP 200, with zero matching lines for the PEAR creation message or command output in the saved response.

CVE-2026-87902 CTEM CVE-2026-87902 Best CTEM Platform. CTEM

Figure 5: The patched inclusion request saved a complete 20,756-byte response. The saved response contains no uid output or target filename; the normal page title appears in the body.

CVE-2026-87902 CVE-2026-87902 Best CTEM Platform

Figure 6: The file is absent on WordPress 7.1.2 after the patched requests. The hashes tie this check to the two full response files from the follow-up run.

Demonstrated Impact

On WordPress 7.1.1, the September 29 run establishes an absent target file, a PEAR write response, HTTP output from id, and a www-data-owned file. A later follow-up against 7.1.2 saved both complete responses, found no exploit output in either, and confirmed the file remained absent. The observed command ran in the vulnerable lab container as the web-server account.

CVE-2026-87902 Best CTEM Platform

Figure 7: Impact recap from Figure 3. This repeats the September 29 HTTP command output and file listing, not another execution.

See how SAFE transforms your CTEM Unified exposure visibility, AI-driven prioritization, and quantified risk in business terms. Built for enterprise scale.