CVE-2026-87902: Critical Unauthenticated Local File Inclusion in WordPress Core (Conditional RCE)
CVE-2026-87902 (TL-2026-2623) is a critical-severity software vulnerability scored CVSS 9.2, first published 2026-09-22. It has no confirmed attribution, affects WordPress WordPress Core, references 1 CVE (CVE-2026-87902), maps to 9 MITRE ATT&CK techniques (T1005, T1027, T1059), and is covered by 9 detection rules and 15 indicators of compromise.
Key facts for TL-2026-2623
- Threat ID
- TL-2026-2623
- Severity
- CRITICAL
- CVSS
- 9.2 (AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H)
- Status
- ACTIVE
- Category
- VULNERABILITY
- First published
- 2026-09-22
- Last reviewed
- 2026-09-22
- Attribution confidence
- LOW
- Motivation
- UNKNOWN
- Detection rules
- 9
- Indicators of compromise
- 15
Malware and tooling in CVE-2026-87902
Malware and tooling: PHP, pear, CVE-2026-87902-Abraxas-Labs.py, cve-2026-87902.py
An unauthenticated attacker can abuse WordPress core's get_page_template() page-template resolution to include an arbitrary readable local .php file outside the active theme directory, via a double URL-encoded pagename query parameter that survives sanitization and is later decoded, letting traversal reach files such as PHP's pearcmd.php. On servers where the active theme has a top-level page-* directory and register_argc_argv is enabled (default in official Docker PHP images and common on cPanel/PHP<8.5), the LFI chains into full remote code execution. WordPress 7.1.2 (with backports to 7.0.6, 6.9.9, 6.8.10, 6.7.9, 6.6.9, and 4.7.37) fixes the flaw; multiple public PoCs exist and Patchstack observed the first exploitation probes roughly 5 hours after the patch shipped.
How CVE-2026-87902 works
CVE-2026-87902 is a critical (CVSS 9.2, CVSS4 vector AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H; NVD also lists CVSS 3.1 8.1, AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H) path-traversal-to-local-file-inclusion vulnerability (CWE-98, Improper Control of Filename for Include/Require in PHP) in WordPress core versions 4.7.0 through 7.1.1, affecting the decade-plus of releases in that range. The root cause is in wp-includes/template.php inside get_page_template(): when WordPress resolves which template to render for a requested page, it builds a candidate filename by concatenating a caller-influenced value onto a fixed 'page-' prefix and '.php' suffix. A neighboring code branch three lines away already applies a validate_file() containment check before using similar input; the pagename branch does not, an inconsistency in security controls across otherwise-similar operations that Robert Ressl (the discoverer) documented in his write-up and PoC.
The practical exploitation path relies on double URL-encoding: WordPress's request sanitizer strips literal '../' sequences but does not recognize percent-encoded octets (e.g. %252e%252e, i.e. '..' encoded twice), so a payload like 'templates%252f%252e%252e%252f...' survives the initial filter. Later, when get_page_template() calls urldecode() on the pagename value, the encoded traversal sequence is converted into real '../' path segments, and locate_template() concatenates the now-decoded value onto the theme path without re-validating containment. template-loader.php then includes whatever file that traversal resolves to, provided it exists and is readable, without confirming the resolved path stays inside an allowed theme directory. WordPress 7.1.2 closes this two ways: it applies validate_file() to the pagename branch to match the sibling branch, and adds a new _wp_is_template_path_allowed() containment check requiring all resolved template paths to remain inside allowed theme directories -- a defense-in-depth response suggesting broader concern about the template-resolution surface generally.
By itself the flaw is 'only' unauthenticated arbitrary local .php file inclusion (an attacker chooses which readable .php file on the server executes, not what code it runs) -- serious LFI, but not automatically RCE. Four conditions must align for the documented RCE chain: (1) a published, anonymous-accessible Page selectable via page_id with no custom template already assigned, (2) the active theme containing a top-level directory beginning with 'page-' (common in legacy default themes such as Twenty Twelve and Twenty Fourteen, and in themes like Neve, Hestia, and Sydney), (3) a readable .php file reachable via traversal that has exploitable runtime behavior, and (4) that file's environment supporting arbitrary content generation. Ressl's laboratory chain used PHP's bundled PEAR command-line entry point, pearcmd.php, which reads command-line-style arguments out of $_SERVER['argv'] when the PHP ini directive register_argc_argv is enabled -- the default in the official PHP Docker images and common in cPanel hosting running PHP versions below 8.5. A first unauthenticated request abuses pearcmd.php's config-create functionality (invoked via a crafted 'pagename' that traversal-includes it, with query-string content acting as PEAR CLI arguments) to write a second, attacker-controlled PHP file to a writable temp directory; a second request re-exploits the same LFI to include that generated file, achieving code execution as the web server's account (www-data in testing). Ressl explicitly cautions that his evidence 'does not establish' that every default WordPress installation is exploitable to full RCE -- the chain is environment-dependent (PEAR availability, register_argc_argv, writable temp paths), not a WordPress-specific guarantee -- but the underlying unauthenticated LFI is present in every affected core version regardless of those conditions.
WordPress disclosed and patched the issue on 2026-09-22. Independent of the vendor advisory, Robert Ressl published a detailed technical write-up and a Docker-based reproduction lab (pinned to wordpress:7.0.2-php8.3-apache with register_argc_argv deliberately enabled) at ressl.ch, and at least two further public PoC repositories (GitHub user abraxas, and a listing by 'pwnVader' indexed on Sploitus) appeared the same day, each independently demonstrating the traversal-to-inclusion primitive with slightly different encoding depth and target-file choices. Patchstack's WAF telemetry recorded the first exploitation probes at 2026-09-22T17:44Z -- under five hours after the WordPress.org patch release -- from a small, concentrated cluster of source addresses (two neighboring IPv4 hosts plus supplementary IPv6 traffic) using automated Go-http-client requests with double-encoded traversal against wp-links-opml.php, wp-includes/functions.php, and wp-cron.php as detection targets; as of the most recent telemetry (2026-09-22T19:51Z) this activity remained reconnaissance/fingerprinting rather than confirmed payload delivery, and the CVE had not yet been added to the CISA KEV catalog. Given WordPress's ~43% share of the web and the fact that a large majority of live installs lag the latest release, and the unusually deep backport (patches were issued all the way back to the 4.7 branch, first released in 2016), the vendor's own patch scope signals broad recognized exposure across long-lived, infrequently-updated WordPress deployments.
MITRE ATT&CK techniques used in TL-2026-2623
Collection
Defense Evasion
T1027 Obfuscated Files or Information; T1140 Deobfuscate/Decode Files or Information
Execution
T1059 Command and Scripting Interpreter
Initial Access
T1190 Exploit Public-Facing Application
Persistence
Resource Development
Reconnaissance
Affected products and versions in CVE-2026-87902
- WordPress — WordPress Core
Vulnerable versions: 4.7.0-7.1.1
Fixed in: 7.1.2; 7.0.6; 6.9.9; 6.8.10; 6.7.9; 6.6.9; 4.7.37
Remediation for CVE-2026-87902
Patches
- WordPress 7.1.2
- WordPress 7.0.6
- WordPress 6.9.9
- WordPress 6.8.10
- WordPress 6.7.9
- WordPress 6.6.9
- WordPress 4.7.37
Immediate actions
- Update WordPress core to 7.1.2 (7.1 branch), 7.0.6 (7.0 branch), 6.9.9, 6.8.10, 6.7.9, 6.6.9, or 4.7.37 (legacy branches down to 4.7) as applicable to your installed line.
- If immediate patching is not possible, check whether the active theme contains a top-level directory whose name begins with 'page-' (e.g. page-templates/) and treat any such site as high exposure pending the update.
- Disable register_argc_argv in php.ini on any internet-facing PHP host where it is not explicitly required; it is on by default in the official PHP Docker images and on many cPanel/PHP<8.5 hosting stacks.
- Remove or restrict web access to unused PEAR command-line entry points such as pearcmd.php on production web servers.
- Deploy a WAF/edge rule blocking percent-encoded traversal sequences (e.g. %252e%252e, %252f) in the pagename query parameter, which Patchstack identifies as a reliable detection/blocking signal for this specific flaw.
Workarounds
- Block or rewrite requests containing percent-encoded traversal sequences in the pagename query parameter at the WAF/reverse-proxy layer.
- Disable register_argc_argv and remove web-readable pearcmd.php to break the documented RCE escalation path even if the LFI itself cannot be immediately patched.
Longer-term hardening
- Restrict the PHP process account's filesystem read access and remove write access to temp/upload directories where not required, to break the write-then-include RCE chain even if a future LFI-class bug is found.
- Monitor WordPress core, theme, and plugin update channels and reduce time-to-patch for internet-facing installs, given the observed <5 hour window between patch release and first exploitation probes.
- Audit legacy/default themes (Twenty Twelve, Twenty Fourteen, Neve, Hestia, Sydney, and any others with page-prefixed top-level directories) across managed WordPress fleets and prioritize their remediation.
CVEs associated with CVE-2026-87902
CVE-2026-87902
Weaknesses (CWE) in CVE-2026-87902
CWE-98
Timeline of CVE-2026-87902
- Robert Ressl privately discloses CVE-2026-87902 to the WordPress security team via HackerOne, ahead of the September 2026 public patch.
- As of publication, CVE-2026-87902 has not been added to the CISA Known Exploited Vulnerabilities catalog.
- Patchstack's most recent recorded activity at time of reporting (19:51 UTC) shows continued reconnaissance/fingerprinting probes against wp-links-opml.php, wp-includes/functions.php, and wp-cron.php, with no confirmed successful payload delivery yet observed in their telemetry.
- Patchstack's WAF telemetry records the first in-the-wild probing/exploitation attempts at 17:44 UTC, under five hours after the patch's release, from a small cluster of source addresses (169.58.48.193, 169.58.48.195, and IPv6 2001:df1:e8c0::106b) using automated Go-http-client requests with double-URL-encoded traversal payloads.
- The Hacker News publishes coverage of the WordPress patch and the conditional-RCE flaw, surfacing it to a broad audience of administrators.
- A third independent exploit, authored by 'pwnVader', is indexed on the Sploitus exploit-aggregation site, using an empty-body POST detection technique against wp-includes/version.php.
- Independent public proof-of-concept exploit code is published on GitHub by user abraxas (CVE-2026-87902 repository) with its own reproduction script and lab fixture.
- Robert Ressl publishes a detailed technical write-up and a Docker-based reproduction lab (pinned wordpress:7.0.2-php8.3-apache image) at ressl.ch demonstrating the full LFI-to-RCE chain via pearcmd.php.
- WordPress publishes GitHub Security Advisory GHSA-7hp8-65ch-5whp detailing the flaw and patched version list.
- CVE-2026-87902 is published in the NVD at 17:17:28 UTC with a CVSS 3.1 base score of 8.1 (WordPress/GHSA separately rate it 9.2 under CVSS 4.0).
- WordPress releases 7.1.2 and backported fixes (7.0.6, 6.9.9, 6.8.10, 6.7.9, 6.6.9, and 4.7.37) closing CVE-2026-87902 by adding validate_file() checks and a new _wp_is_template_path_allowed() containment function.
Sources cited for CVE-2026-87902
- WordPress Issues Patch for Critical Flaw That Can Enable Code Execution on Some Servers
- Unauthenticated path traversal in page-template resolution leading to conditional RCE (GHSA-7hp8-65ch-5whp)
- NVD - CVE-2026-87902 Detail
- CVE-2026-87902 WordPress technical write-up and PoC lab
- ressl/cve-2026-87902-poc: PoC for unauthenticated path traversal in WordPress page-template resolution
- abraxas/CVE-2026-87902: Unauthenticated Local File Inclusion (conditional RCE)
- CVE-2026-87902: Attackers Started Probing WordPress Sites Hours After the Patch
- WordPress 7.1.2 Security Release: Unauthenticated LFI to RCE
- CVE-2026-87902: WordPress RCE Flaw Already Exploited
- CVE-2026-87902: Critical WordPress RCE Flaw Fixed in Version 7.1.2
- pwnVader exploit listing for CVE-2026-87902
More in vulnerability
- BigDiskBuster PoC Blocks Microsoft Defender Antivirus Updates via Disk-Space Exhaustion
- Check Point Patches Actively Exploited Zero-Day Path Traversal in Management Server (CVE-2026-93616)
- BigDiskBuster PoC Blocks Windows Defender Signature/Platform Updates (DoS)
- Zyxel GS1900 Series Switches Stack-Based Buffer Overflow (CVE-2026-7273) Actively Exploited by Kapibala/Red Heron in Global 996-Device Campaign — Added to CISA KEV
- Click2Shell: WordPress Theme-Preview CSRF/Selector-Injection Chain to Forced Theme Install
Detection coverage for TL-2026-2623
As of 2026-09-22, Threadlinqs Intelligence publishes 9 detection rule(s) for TL-2026-2623 across Splunk SPL, Microsoft KQL and Sigma, covering 15 indicator(s) of compromise. The whole corpus is readable without an account; a free account unlocks full detection query text in Splunk SPL, Microsoft KQL and Sigma; paid tiers add raw indicator values, correlation and the MCP server. Threadlinqs MCP server · View plans.