Skip to navigation

Threat reportVulnerabilityTL-2026-2623

CVE-2026-87902: Critical Unauthenticated Local File Inclusion in WordPress Core (Conditional RCE)

criticalACTIVE

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.

Key facts for WordPress path traversal RCE

IdentifiersTL-2026-2623, CVE-2026-87902
SeverityCRITICAL
CVSS9.2 (AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H)
Exploitation statusExploited in the wild
Affected productsWordPress WordPress Core
Weaknesses (CWE)CWE-98, CWE-22
MalwarePHP, pear
ToolsCVE-2026-87902-Abraxas-Labs.py, cve-2026-87902.py
MITRE ATT&CK techniquesT1005 Data from Local System, T1027 Obfuscated Files or Information, T1033 System Owner/User Discovery, T1059 Command and Scripting Interpreter, T1059.004 Command and Scripting Interpreter, T1082 System Information Discovery, T1083 File and Directory Discovery, T1105 Ingress Tool Transfer, T1140 Deobfuscate/Decode Files or Information, T1190 Exploit Public-Facing Application, T1505.003 Web Shell, T1518 Software Discovery and 7 more in the attack flow
MotivationUNKNOWN
Detection rules9 (1 shown free)
Sources11 cited sources

Detection coverage for WordPress path traversal RCE

As of 2026-09-27, Threadlinqs Intelligence publishes 9 detection rule(s) for TL-2026-2623 across Splunk SPL, Microsoft KQL and Sigma, covering 48 indicator(s) of compromise. The whole corpus is readable without an account. Every threat comes with one complete detection in Splunk SPL, Microsoft KQL and Sigma, free for everyone; a free account adds daily TL Creds to unlock the rest. Paid plans add a larger daily allowance, correlation and the MCP server. Threadlinqs MCP server · View plans.

Free detection: WordPress CVE-2026-87902 Double URL-Encoded Pagename Traversal Probe — Exploitation

Detects the unauthenticated exploitation primitive for CVE-2026-87902: requests carrying a double URL-encoded traversal sequence (%252e%252e / %252f) in the pagename query parameter, or requests fingerprinting the vulnerable install by probing wp-links-opml.php, wp-includes/functions.php, or wp-cron.php — the exact target set Patchstack observed in the first in-the-wild probes ~5 hours after the 7.1.2 patch.

  • Languages: Splunk SPL, Microsoft KQL, Sigma
  • ATT&CK: T1190, T1595.002
  • Data sources: web_server_access_logs, waf_logs, w3c_iis_log
  • Severity: high
  • Confidence: high

Splunk SPL

index=web sourcetype=access_combined
| rex field=uri_query "pagename=(?<pagename_val>[^&]+)"
\`comment("CVE-2026-87902: WordPress literal-'../'  sanitizer misses percent-encoded octets; urldecode() inside get_page_template() later reveals the traversal.")\`
| where match(uri_query, "%252[eE]%252[eE]") OR match(uri_query, "%252[fF]") OR match(uri_path, "(?i)(wp-links-opml\.php|wp-cron\.php|wp-includes/functions\.php)")
| eval double_encoded_traversal=if(match(uri_query,"%252[eE]%252[eE]"),1,0)
| eval is_scan_ua=if(match(useragent,"(?i)Go-http-client"),1,0)
| stats count as request_count min(_time) as first_seen max(_time) as last_seen values(uri_path) as targeted_paths values(useragent) as user_agents values(pagename_val) as pagename_values values(double_encoded_traversal) as had_double_encoding by clientip
| where request_count >= 1
| sort -request_count

Microsoft KQL

W3CIISLog
| where TimeGenerated > ago(24h)
// CVE-2026-87902: match either the raw double-encoded traversal payload or the Patchstack-documented fingerprinting target set
| where (csUriQuery has "pagename" and (csUriQuery has "%252e%252e" or csUriQuery has "%252f"))
   or csUriStem has_any ("wp-links-opml.php", "wp-cron.php", "wp-includes/functions.php")
| extend DoubleEncodedTraversal = iif(csUriQuery has "%252e%252e", true, false)
| summarize RequestCount=count(), FirstSeen=min(TimeGenerated), LastSeen=max(TimeGenerated), TargetPaths=make_set(csUriStem), UserAgents=make_set(csUserAgent) by cIP
| where RequestCount >= 1
| sort by RequestCount desc

Sigma

title: WordPress CVE-2026-87902 Double URL-Encoded Pagename Traversal Probe
id: 8f3a1c2e-4b5d-4e6f-9a1b-2c3d4e5f6a7b
status: experimental
description: Detects unauthenticated exploitation probes for CVE-2026-87902, an LFI in WordPress core's get_page_template() reached via a double URL-encoded pagename parameter, or fingerprinting requests against the specific files Patchstack observed scanners targeting.
references:
    - https://github.com/WordPress/wordpress-develop/security/advisories/GHSA-7hp8-65ch-5whp
    - https://patchstack.com/articles/cve-2026-87902-attackers-started-probing-wordpress-sites-hours-after-the-patch/
author: AII-Detector — ThreadLinqs Intelligence
date: 2026-09-22
tags:
    - attack.reconnaissance
    - attack.t1595.002
    - attack.initial-access
    - attack.t1190
    - cve.2026.87902
logsource:
    category: webserver
    product: nginx
detection:
    selection_traversal:
        cs-uri-query|contains:
            - '%252e%252e'
            - '%252E%252E'
    selection_targets:
        cs-uri-stem|contains:
            - 'wp-links-opml.php'
            - 'wp-cron.php'
            - 'wp-includes/functions.php'
    condition: selection_traversal or selection_targets
falsepositives:
    - Authorized vulnerability scanners or pentest tooling exercising the same endpoints
    - Misconfigured reverse proxies that legitimately double-encode query strings
level: high

Known false positives:

  • Authorized vulnerability scanners (Nessus/Qualys) or pentest tooling probing the same endpoints
  • Misconfigured reverse proxies or CDNs that legitimately double-encode query strings
  • Internal security-team validation traffic re-testing the patch

Tuning notes: Baseline known scanner/proxy source IPs into an allowlist lookup to suppress benign double-encoding traffic; escalate severity when the same source hits multiple PoC-specific paths (wp-links-opml.php, wp-cron.php, wp-includes/functions.php) within a short window, matching the Patchstack cluster pattern.

8 more detection rules (Splunk SPL, Microsoft KQL, Sigma) · unlock with TL Creds. Sign up free to unlock the detection rules or query them with the Threadlinqs MCP server (Purple)
  • WordPress CVE-2026-87902 Double URL-Encoded Pagename Traversal Probe — Exploitation · unlock with TL Creds
  • WordPress pearcmd.php Webshell Write & Web-Server-Spawned Shell — Post-Exploitation · unlock with TL Creds
  • Post-RCE Web-Server-Process Public Egress & Repeated Sensitive-Path Recon (CVE-2026-87902) · unlock with TL Creds
  • WordPress CVE-2026-87902 Double URL-Encoded Pagename Traversal Probe — Exploitation · unlock with TL Creds
  • WordPress pearcmd.php Webshell Write & Web-Server-Spawned Shell — Post-Exploitation · unlock with TL Creds
  • Post-RCE Web-Server-Process Public Egress & Repeated Sensitive-Path Recon (CVE-2026-87902) · unlock with TL Creds
  • WordPress pearcmd.php Webshell Write & Web-Server-Spawned Shell — Post-Exploitation · unlock with TL Creds
  • Post-RCE Web-Server-Process Public Egress & Repeated Sensitive-Path Recon (CVE-2026-87902) · unlock with TL Creds

Indicators of compromise for WordPress path traversal RCE

As of 2026-09-27, Threadlinqs Intelligence tracks 48 indicators of compromise for TL-2026-2623.

Sample indicators (3 of 48)

  • IP address: 169.58.48[.]193
  • URL: hxxps://raw[.]githubusercontent[.]com/MrG3P5/web-shell/refs/heads/main/uploader.php
  • IP address: 169.58.48[.]195

Defanged, TLP:CLEAR. Full set of 48 indicators: unlock with TL Creds.

48 indicators of compromise · unlock with TL Creds. Compare plans

How WordPress path traversal RCE works

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.

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 by tactic:

Collection

T1005 Data from Local System

Defense Evasion

T1027 Obfuscated Files or Information; T1140 Deobfuscate/Decode Files or Information

Discovery

T1033 System Owner/User Discovery; T1082 System Information Discovery; T1083 File and Directory Discovery; T1518 Software Discovery

Execution

T1059 Command and Scripting Interpreter; T1059.004 Command and Scripting Interpreter

Command and Control

T1105 Ingress Tool Transfer

Initial Access

T1190 Exploit Public-Facing Application

Persistence

T1505.003 Web Shell

Credential Access

T1552.001 Unsecured Credentials

Resource Development

T1588.002 Obtain Capabilities: Tool; T1588.005 Exploits; T1588.006 Obtain Capabilities; T1608.001 Stage Capabilities: Upload Malware

Reconnaissance

T1592.002 Software; T1595.002 Vulnerability Scanning

Remediation for WordPress path traversal RCE

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.

Affected and fixed versions

  • 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

Timeline of WordPress path traversal RCE

Last updated · 3 updates · revalidated 3× · latest source

  • locked-ioc-42 privately discloses CVE-2026-87902 to the WordPress security team via HackerOne, ahead of the September 2026 public patch.
  • WordPress acknowledges locked-ioc-42's HackerOne report of the page-template path-traversal vulnerability.
  • WordPress informs the reporter that a fix is planned ahead of the 2026-09-22 security release.
  • locked-ioc-45 observes the first pearcmd config-show probes (testing PEAR reachability) at 15:34 UTC, preceding later config-create file-write attempts.
  • locked-ioc-45 reports blocking the first exploitation attempt at 11:49 UTC, earlier than the previously recorded 17:44 UTC first-probe timestamp.
  • As of publication, CVE-2026-87902 has not been added to the CISA Known Exploited Vulnerabilities catalog.
  • locked-ioc-45'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.
  • locked-ioc-45'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 (locked-ioc-35, locked-ioc-36, and IPv6 locked-ioc-25) 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 'locked-ioc-46', 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.
  • locked-ioc-42 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.
  • locked-ioc-45 reports exploitation volume increased more than tenfold as public PoC and Nuclei scanning tooling circulated, with attackers now writing executable PHP payloads to locked-ioc-48 and locked-ioc-47 via pearcmd config-create; BleepingComputer publishes escalation coverage.
  • Security researchers (SecurityArsenal, Security Affairs) publish detailed detection and remediation guidance for CVE-2026-87902, including web-request signatures, filesystem IOCs, and process-behavior indicators for defenders.
  • CISA adds CVE-2026-87902 to its Known Exploited Vulnerabilities catalog based on confirmed evidence of active exploitation.
  • CISA Binding Operational Directive 26-04 remediation deadline for FCEB agencies to apply the WordPress fix and complete forensic triage for prior compromise.

Update history

Sources cited for WordPress path traversal RCE

Previous and next in vulnerability

Drafted by the Threadlinqs research pipeline from 11 sources; published ; last updated .

Threadlinqs Intelligence — Real-Time Threat Detection Platform

[ 0 threats ] [ 0 det ] [ CRIT: 0 ] [ HIGH: 0 ]
// threat_feed
$ sort --newest
Showing all threats

Live intelligence console

Threat level

Latest Threats