# WordPress CVE-2026-87902: Unauthenticated Path Traversal Under Active Attack

URL: https://limehawk.io/reports/wordpress-cve-2026-87902-path-traversal
Published: 2026-09-28
Author: Corey Watson, Managing Member
Topic: Security
Read time: 5 min

CVE-2026-87902 lets an unauthenticated attacker make WordPress 4.7.0 through 7.1.1 include a PHP file outside the theme folder, and on some servers that becomes remote code execution. Update to 7.1.2 or your branch's backport now; it's being exploited.

> **TL;DR** A bug in WordPress core's get_page_template() lets anyone on the internet point the template loader at a readable PHP file outside the theme directory. With the right server setup (a theme with a top-level page- folder and PHP's register_argc_argv turned on), attackers chain it through pearcmd.php to write their own PHP to disk. WordPress shipped 7.1.2 plus backports on September 22, probing started the same day, and CISA added it to the KEV catalog on September 25. Update, then check your logs.

- CVSS v4: 9.2
- Auth required: None
- Affected: 4.7.0–7.1.1
- Fixed in: 7.1.2

## What is CVE-2026-87902?

CVE-2026-87902 is an unauthenticated path traversal bug in WordPress core. The function `get_page_template()` builds a template filename partly from the request, and it didn't properly handle encoded `../` sequences. An attacker can steer it to any readable `.php` file on the server outside the active theme directories, and WordPress runs it.

The CVE record classes it as CWE-98 (PHP file inclusion). The WordPress advisory scores it 9.2 on CVSS v4; the CVE record's CVSS v3.1 score is 8.1, with attack complexity marked high because code execution depends on server setup.

## Which versions are affected?

Every WordPress release from 4.7.0 through 7.1.1. WordPress fixed it in 7.1.2 on September 22, 2026, and backported the fix to 24 older branches, including 7.0.6, 6.9.9, 6.8.10, and 4.7.37. If you're on an older branch, the latest point release on that branch is patched.

Sites with automatic background updates enabled should already have it. Check the version under Dashboard → Updates anyway.

## When does it become remote code execution?

Including a random PHP file is bad; running attacker code is worse. The chain Patchstack observed needs two things on the server:

1. The active theme has a top-level `page-` directory.
2. PHP has `register_argc_argv` enabled, which hands the query string to included scripts as command-line arguments.

With both, attackers include PEAR's `pearcmd.php` and pass it `config-create` arguments, which writes a PHP file of their choosing to disk. From there it's a web shell.

## How are attackers exploiting it?

Patchstack saw the first probe at 11:49 UTC on September 22, the same day the patch shipped. The attacks run in three stages:

- **Check the bug is there.** Requests with `pagename` holding encoded traversal (`%2e%2e` or double-encoded `%252e%252e`) pointing at harmless core files like `wp-links-opml.php` or `wp-includes/feed-rss2.php`.
- **Find PEAR.** The same trick aimed at `pearcmd` with `+config-show`, trying `/usr/local/lib/php/`, `/usr/share/php/`, and `/usr/share/pear/`.
- **Write a file.** `pearcmd` with `+config-create`, a PHP payload, and a path in `/tmp`.

A public Nuclei template landed on September 23, and traffic went up more than tenfold from the first evening. CISA added the CVE to its Known Exploited Vulnerabilities catalog on September 25.

## How do I check whether my site was hit?

Search your web server access logs for:

- A `pagename` parameter containing `%2e%2e` or `%252e%252e`.
- `pagename` and `page_id` together in requests to the site root.
- `pearcmd`, `+config-show`, or `+config-create` anywhere in the URL.
- User agents `cve-2026-87902-poc/1.0` or `nuclei-cve-2026-87902/1.0`.

```
grep -Ei 'pagename=[^& ]*(%2e%2e|%252e%252e)|pearcmd|config-(show|create)|cve-2026-87902' /var/log/nginx/access.log*
```

Then look for PHP files that shouldn't exist, especially in `/tmp` and `/var/tmp`. Names seen so far include `wp-pear-rce-flag.php` and `poc87902.php`.

```
find /tmp /var/tmp -name '*.php' -newermt 2026-09-22 -ls
```

Probes against core files only prove someone scanned you. A `config-create` request that returned 200, or a new PHP file on disk, means treat the server as compromised: take it offline, rotate credentials and salts, and rebuild from a known-good backup.

## What if I can't update right now?

Update. If something truly blocks it for a few hours:

- Set `register_argc_argv = Off` in php.ini and reload PHP-FPM. That breaks the pearcmd chain.
- Block requests where `pagename` contains `..`, `%2e%2e`, or `%252e%252e` at your WAF or reverse proxy.

Both reduce exposure. Neither fixes the bug.

## Sources

- [CVE record, CVE-2026-87902](https://www.cve.org/CVERecord?id=CVE-2026-87902)
- [Patchstack: attackers started probing WordPress sites hours after the patch](https://patchstack.com/articles/cve-2026-87902-attackers-started-probing-wordpress-sites-hours-after-the-patch/)
- [Help Net Security: WordPress 7.1.2 fixes critical path traversal](https://www.helpnetsecurity.com/2026/09/23/cve-2026-87902-wordpress-7-1-2-security-release/)

- Sep 9 — CVE ID reserved.
- Sep 22 — WordPress 7.1.2 released, with fixes backported to every branch back to 4.7.
- Sep 22, 11:49 UTC — First exploitation attempt seen by Patchstack, probing harmless core files.
- Sep 22, 15:34 UTC — First file-write attempts through pearcmd.php.
- Sep 23 — Public Nuclei template released; attack traffic spikes.
- Sep 25 — CISA adds CVE-2026-87902 to the Known Exploited Vulnerabilities catalog.

- Update to 7.1.2, or the patched release on your branch (7.0.6, 6.9.9, 6.8.10 … down to 4.7.37).
- Background auto-updates should have applied it. Confirm the version; don't assume.
- Turn off register_argc_argv in php.ini. It breaks the known RCE chain and web servers don't need it.
- Grep access logs for traversal in pagename and for pearcmd. Probing started hours after the patch.
- Look for stray .php files in /tmp and /var/tmp.
