Security Digest · Sep 22, 2026 · Vulnerability · Web framework

WordPress Core: Page-Template File Inclusion to RCE

Unauthenticated file inclusion in WordPress 4.7-7.1.1 can reach RCE via pearcmd.php. Fixed in 7.1.2 and backports. In CISA KEV. Update now.

Our verdict

Act now

Every WordPress branch back to 4.7 was affected, no login is needed, public scanning tooling exists and attackers are already writing files through pearcmd.php, so confirm you are on a fixed release today.

Who must act: Anyone running self-managed WordPress 4.7 through 7.1.1, especially with a theme that has a top-level page-* directory or PHP with register_argc_argv enabled (official php Docker images, cPanel on PHP below 8.5).

Who can relax: Sites already on 7.1.2 or the patched release for their branch (auto-updates usually handled this), and managed hosts that have confirmed the update in writing.

Affected
WordPress 7.1.0-7.1.1
WordPress 7.0.0-7.0.5
WordPress 6.9.0-6.9.8
WordPress 6.8.0-6.8.9
Every branch from 4.7.0 up to its patched release
Fixed in
WordPress 7.1.2
WordPress 7.0.6
WordPress 6.9.9
WordPress 6.8.10
Backports for every branch down to 4.7.37
CVSS
9.2 (v4.0, vendor)
EPSS
40.0% (percentile 99)
CISA KEV
Yes, listed as known exploited
Exploitation
Exploited in the wild
Severity
Critical

What to do

  1. Confirm each site reports 7.1.2 or the patched release for its branch (wp core version).
  2. Update now from Dashboard > Updates or with wp core update --minor; do not wait for the next maintenance window.
  3. If you cannot update immediately, block requests whose pagename parameter contains encoded traversal (%2e%2e, %252e%252e).
  4. Set register_argc_argv = Off in php.ini where you do not need it, which breaks the pearcmd.php route to code execution.
  5. Check whether your active theme or parent theme has a top-level page-* directory (for example page-templates).
  6. Hunt for unexpected .php files in /tmp and /var/tmp on any host that was unpatched after September 22.

How to check if you are affected or compromised

  • Search access logs for a pagename parameter containing %2e%2e or %252e%252e, or starting with templates%2f, in the query string or POST body.
  • Flag requests that pair pagename with page_id on / or /index.php, or that contain pearcmd, +config-show or +config-create.
  • Look for the user agents cve-2026-87902-poc/1.0 and nuclei-cve-2026-87902/1.0 (most attack traffic spoofs browsers, so absence proves nothing).
  • Treat unexpected .php files in /tmp or /var/tmp, or OPML/RSS output returned from a normal page URL with HTTP 200, as signs the inclusion ran.

What happened#

On September 22, 2026, WordPress shipped version 7.1.2, a security-only release with a single fix, and backported it to every branch back to 4.7. The advisory (CVE-2026-87902, rated critical, CVSS 4.0 score 9.2) says an unauthenticated attacker can make get_page_template() include a chosen readable local .php file from outside the active theme directories. Under certain server and theme conditions, that leads to remote code execution. Robert Ressl reported it.

Patchstack's analysis shows the root cause. WordPress builds a template candidate named page-{pagename}.php from the request's pagename variable, adds a URL-decoded copy, and never passes it through the validate_file() traversal check that the neighboring branch already used. The fix adds that check, plus a new containment test that every resolved template path must pass. CISA added the CVE to the KEV catalog on September 25 with a September 28 due date for federal agencies.

Who is affected#

Every WordPress release from 4.7.0 through 7.1.1, which is close to a decade of versions. Fixed releases include 7.1.2, 7.0.6, 6.9.9 and 6.8.10, plus backports on each older branch down to 4.7.37. NVD lists a CISA-ADP CVSS 3.1 score of 8.1 because the attack has preconditions. The advisory names two of them:

  • Theme: the active child or parent theme has a top-level directory whose name starts with page-, such as page-templates. This applies to the legacy Twenty Twelve and Twenty Fourteen themes and to popular third-party themes including Neve, Hestia and Sydney.
  • Server: a useful .php target is readable. The well-known one is PEAR's pearcmd.php, which works when register_argc_argv is On. That is the case in the official php Docker image and in default cPanel setups on PHP before 8.5.

Do you really need to act?#

Yes, if you run WordPress yourself and are not yet on a fixed release. File inclusion works on any vulnerable site that meets the theme condition. Code execution also needs the server condition, but as Patchstack notes, those settings are common defaults rather than unusual ones.

Exploitation began fast. Patchstack logged first attempts at 11:49 UTC on September 22, built from the patch diff, and the first attempt to write a file through pearcmd at 15:34 UTC. By September 23 traffic had grown more than tenfold and moved through three stages: checking whether the inclusion worked, checking whether pearcmd was reachable, and writing attacker-controlled PHP to /tmp with +config-create. A named Nuclei template was in circulation. Some payloads only drop marker strings, but others run shell commands.

Sites with automatic background updates usually received the fix already. Managed WordPress hosts generally patch core for you, but get confirmation rather than assuming.

What to do now#

  1. Check the version on every site: wp core version, or Dashboard > Updates.
  2. Update: wp core update --minor to take the patched release on your branch, or wp core update for 7.1.2. Older sites can take the backport without a major version jump.
  3. If you cannot update today, block requests where pagename contains %2e%2e or %252e%252e, in the query string or the POST body. Real page slugs never contain traversal.
  4. Set register_argc_argv = Off in php.ini where you do not need it, and restart PHP. This does not fix the inclusion, but it breaks the pearcmd chain.
  5. Check your theme: ls wp-content/themes/<theme>/ | grep '^page-'.

How to tell if you were hit#

Patchstack's indicators: a pagename parameter containing %2e%2e or %252e%252e, or starting with templates%2f. Also watch for pagename paired with page_id on / or /index.php, any request containing pearcmd, +config-show or +config-create, and the user agents cve-2026-87902-poc/1.0 and nuclei-cve-2026-87902/1.0. An HTTP 200 that returns OPML or RSS output for a normal page URL means a probe succeeded. Run find /tmp /var/tmp -name '*.php' on the host. Patchstack observed filenames such as poc87902.php, wp-pear-rce-flag.php, luci_*.php and zeta_*.php. If you find any, treat the host as compromised: rebuild it, and rotate database credentials and secrets stored in wp-config.php.

Timeline#

  • — WordPress 7.1.1 ships with 11 unrelated security fixes.
  • — WordPress 7.1.2 and backports to 4.7 are released, and GHSA-7hp8-65ch-5whp and CVE-2026-87902 are published. Patchstack sees probing the same day and the first pearcmd file-write attempt at 15:34 UTC.
  • — Patchstack reports file writes to /tmp, a tenfold rise in volume, and a public Nuclei template.
  • — CISA adds CVE-2026-87902 to KEV, due September 28.

Vulnerability records

  • CVE-2026-87902 · KEV 2026-09-25 · An unauthenticated attacker can make `get_page_template()` page-template resolution include a chosen readable local `.php` file outside the active theme…

Sources

Original sources first: vendor and project advisories, CVE and government records, the discoverers’ write-ups. Every claim above links to one of these. See how the Security Desk works.

Original and primary sources

  1. WordPress / GitHub — GHSA-7hp8-65ch-5whp: Unauthenticated path traversal in page-template resolution github.com
  2. WordPress.org — WordPress 7.1.2 Security Release wordpress.org
  3. NVD — CVE-2026-87902 nvd.nist.gov
  4. CISA — Known Exploited Vulnerabilities Catalog: CVE-2026-87902 cisa.gov
  5. Patchstack — WordPress 7.1.2 Security Release: Unauthenticated LFI to RCE patchstack.com
  6. Patchstack — CVE-2026-87902: Attackers Started Probing WordPress Sites Hours After the Patch patchstack.com