high Cve 2026 87902 · Exploits

WordPress Core Flaw CVE-2026-87902 Drew Exploit Attempts on Patch Day

Data graphic: a timeline of WordPress core flaw CVE-2026-87902 CVSS 4.0 9.2 , zooming into 22 September, the day the fix shipped in 25 releases. Patchstack logged the first exploit attempt at 11:49 UTC and the first pearcmd.php file-write attempt at 15:34 UTC that same day; the bug had been reported 64 days earlier on 20 July, and CISA added it to KEV on 25 September with a 28 September deadline.
AK

Threat intelligence editor · Updated Oct 2, 2026, 8:05 AM EDT

A WordPress core path traversal, CVE-2026-87902, can reach RCE through pearcmd.php. Probes began the day the fix shipped and CISA lists it as exploited.

WordPress fixed a flaw in its own core on 22 September 2026 that lets an unauthenticated visitor make a site load a PHP file of the attacker's choosing from outside the active theme. On some combinations of theme and server, that becomes remote code execution. Attackers did not wait long: Patchstack logged the first exploitation attempt at 11:49 UTC that same day, and the researcher who found the bug published a working proof of concept alongside the advisory. CISA added the flaw to its Known Exploited Vulnerabilities catalog on 25 September.

The bug is CVE-2026-87902, an improper control of filename for an include statement (CWE-98) in the get_page_template() function. It affects every WordPress release from 4.7.0 through 7.1.1. WordPress rates it 9.2 Critical under CVSS 4.0, with the vector flagging that attack requirements are present (AT:P). CISA's own scoring puts it at 8.1 High under CVSS 3.1, with high attack complexity. Both numbers say the same thing in different ways: anyone on the internet can send the request, but whether it ends in code execution depends on how the site is built and hosted.

This is not a plugin bug. It sits in WordPress core, so the question for site owners is not whether they run some obscure add-on but whether their theme and their PHP setup meet the conditions below.


Who is affected

Every branch from 4.7 onward received a fix: 25 releases in all, published on 22 September.

BranchFixed release
7.17.1.2
7.07.0.6
6.96.9.9
6.86.8.10
6.76.7.9
6.0 to 6.66.6.9, 6.5.12, 6.4.12, 6.3.12, 6.2.13, 6.1.14, 6.0.16
5.0 to 5.95.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.7 to 4.94.9.33, 4.8.32, 4.7.37

Sites that accept automatic background updates should already have the fix. Sites with background updates turned off, managed hosts that pin versions, and anything running a forked or vendored copy of core need a manual update.

Being on a vulnerable version is not enough for code execution. Three things have to line up.

1. The active theme has a top-level directory whose name starts with page-. WordPress's own theme documentation suggests page-templates/ as a place to keep custom page templates, so this is a normal layout. The advisory names the legacy Twenty Twelve and Twenty Fourteen themes and the popular third-party themes Neve, Hestia and Sydney as affected. The current default themes the researcher inspected, Twenty Twenty-Three through Twenty Twenty-Five, do not have such a directory.

2. A readable PHP file on the server does something useful when included. The well-known target is PEAR's pearcmd.php, which accepts command-line style arguments from the query string when PHP's register_argc_argv setting is On. The advisory says the official php Docker image is affected, and so is the default cPanel configuration when PHP older than 8.5 is in use.

3. Nothing confines PHP's file access, such as open_basedir, and the web server user can write somewhere, typically /tmp.

The PoC also needs a published page that anonymous visitors can reach, without a custom template already assigned to it. Most sites have one.

How the attack works

The researcher, Robert Ressl, reported the flaw through HackerOne on 20 July and published his write-up and lab on the day of the fix. His analysis describes four steps that fail one after another:

  1. Sanitization runs too early. WordPress cleans the pagename query variable, but the cleaner rewrites literal dots and slashes and leaves percent-encoded octets alone. A double-encoded traversal sequence such as %252e%252e survives it.
  2. Page lookup and template lookup disagree. The attacker selects a real page with page_id, so the request resolves, while the poisoned pagename stays in the query object for template resolution.
  3. Decoding happens late. get_page_template() runs urldecode() on the slug and builds a candidate path with a fixed page- prefix and .php suffix. The encoded separators turn back into real ../ at this point.
  4. No containment check. The loader checks that the resolved file exists, is readable and ends in .php, but never checks that it is still inside the theme directory.

The fixed page- prefix is why the theme precondition matters. The traversal has to start from a real directory whose name begins with page-, such as page-templates/, before it can climb out of the theme.

Data graphic: the CVE-2026-87902 attack path. A crafted URL with a double-encoded pagename passes the slug sanitizer, get_page_template decodes it with no theme-directory check, pearcmd.php is included and code runs as the web user. CVSS 4.0 9.2; needs a theme page- directory, readable pearcmd.php with register_argc_argv On, and no open_basedir.

How a single unauthenticated request climbs out of the theme directory, and the three conditions it needs to end in code execution. Sources: Robert Ressl, WordPress advisory GHSA-7hp8-65ch-5whp.

From there, including pearcmd.php with register_argc_argv enabled lets the attacker pass PEAR commands in the URL. Its config-create command writes a file with attacker-controlled content to a writable path, and a second request includes that file. The code runs as the web server user.

Ressl's proof of concept is public at github.com/ressl/cve-2026-87902-poc. Its lab pins the wordpress:7.0.2-php8.3-apache Docker image, adds an empty page-templates/ directory to Twenty Twenty-Five, and turns register_argc_argv on. Several other repositories with toolkits and scanners built on it have since appeared on GitHub.

What attackers are doing

Patchstack, which runs a WordPress firewall, published a running account of the traffic it blocked:

  • 22 September, 11:49 UTC. The first exploitation attempt, probing harmless core files such as wp-links-opml.php, wp-cron.php and install.php to confirm the traversal works.
  • 22 September, 15:34 UTC. The first attempt to write a file to disk through pearcmd.php.
  • 23 September. Public scanning tools circulated, and volume peaked around midday UTC.

By its update, Patchstack said traffic was running at more than ten times the volume of the first evening and had spread from a small cluster of addresses to a few hundred. Attackers checked three standard PEAR locations (/usr/local/lib/php/pearcmd.php, /usr/share/php/pearcmd.php and /usr/share/pear/pearcmd.php) and used config-create to write PHP files into /tmp and /var/tmp. Patchstack does not say whether any of those attempts succeeded on a real site.

CISA's KEV entry, titled "WordPress Core Remote File Inclusion Vulnerability", records exploitation as active and set a remediation deadline of 28 September for US federal civilian agencies. The entry is flagged for forensic triage under BOD 26-04, which means agencies are expected to look for compromise, not only to patch. Use in ransomware campaigns is listed as unknown.


What to do

Update core now. Move to the fixed release for your branch from the table above, and confirm the version in the dashboard or with wp core version rather than assuming the auto-updater ran.

If you cannot update today, these break the demonstrated route to code execution but do not fix the inclusion bug itself:

  • Set register_argc_argv = Off in the PHP configuration used for web requests.
  • Remove PEAR, or at least make pearcmd.php unreadable to the web server user, if nothing needs it.
  • Set open_basedir and restrict where the PHP user can write.
  • At the firewall or WAF, reject requests whose pagename parameter contains %2e%2e or %252e%252e, and requests that combine pagename with page_id on the site root or index.php.

Check whether you were targeted. Patchstack's indicators:

  • pagename values containing %2e%2e or %252e%252e in access logs.
  • Requests containing pearcmd, +config-show or +config-create.
  • The user agents cve-2026-87902-poc/1.0 and nuclei-cve-2026-87902/1.0.
  • Unexpected .php files in /tmp or /var/tmp.

A site that matched all three preconditions and was unpatched after 22 September should be treated as potentially compromised: review recently written PHP files across the web root and temp directories, rotate database and admin credentials, and check for new administrator accounts.

Sources

Keep reading

All latest →
  1. criticalExploitsCheck Point Management Servers Were a Zero-Day for Two Months Before the Fix6 min
  2. criticalExploitsCisco SD-WAN Manager Zero-Day CVE-2026-76504: One Encoded Character Unlocks the Admin API5 min
  3. criticalExploitsExploited FortiMail Flaw Has No Patch Yet: Disable IBE Now5 min
  4. criticalExploitsCitrix NetScaler Zero-Days Planted Webshells Weeks Before the Patch8 min
  5. criticalExploitsUnder Active Attack: Cisco ISE Zero-Day (CVE-2026-76460) Grants Remote Unauthenticated Admin Access8 min
  6. criticalExploitsShieldCrash Zero-Day Analysis: Bypassing Microsoft Defender's ShieldBreak Fix (CVE-2026-69414) for Arbitrary SYSTEM File Reads7 min