Unauthenticated local file inclusion through get_page_template()
An unauthenticated request can steer the template lookup of a page, so WordPress includes any readable .php file on disk outside the theme directory. With a theme condition and one readable PHP file, the flaw leads to code execution.
What happens
get_page_template() chooses the template file for a page; the flaw lets the result point outside the active theme directory, at any readable .php file.
Conditions named in the advisory: the theme has a directory whose name starts with page-, and the machine holds a readable PHP file such as pearcmd.php with register_argc_argv on.
Those conditions are cheap on shared hosting: default and popular themes ship a page- directory, and a readable PHP file is usually there already — another site's, or a backup's.
The path in
- An unauthenticated HTTP request steers the page's template lookup.
- A readable PHP file on the same machine is the other half of the condition: it does not have to belong to the site that is reached, it only has to be readable.
- A backup inside a web directory: no vhost serves it, so it is not an entry point by itself, but it is still readable PHP — that is, the condition for another site on the same machine.
Which files count
- Core on disk: the fix replaces core files, within the line you run.
- The active theme: the condition lives in the theme's directory structure. Changing theme is not a fix, and not every theme has a
page-directory. - Other sites and backups on the same machine: they do not run the vulnerable WordPress, but they supply a readable PHP file.
Running is not installed
- After replacing core files, restart FPM so the new code is certainly running; opcache usually revalidates, but not always.
- Verify core checksums after the upgrade: a hand-edited core file can make the fix ineffective.
Affected and fixed versions
| Product | CVE | Affected | Fixed in |
|---|---|---|---|
| WordPress | CVE-2026-87902 | 7.1.x | 7.1.2 |
7.0.x | 7.0.6 | ||
6.9.x | 6.9.9 | ||
6.8.x | 6.8.10 | ||
6.7.x | 6.7.9 | ||
6.6.x | 6.6.9 |
19 more lines — the full list: Every WordPress vulnerability
Original description (WordPress · CVE-2026-87902): An unauthenticated attacker can make `get_page_template()` page-template resolution include a chosen readable local `.php` file outside the active theme directories. If relevant pre-conditions for both the server and the active theme are met, this can lead to RCE.
What to do
- Update core within the line you run; the table above lists the fixed release for each line.
- Remove readable PHP outside the served directory: backups, old directories, files of retired sites.
- If you cannot update yet: restrict read access to PHP outside the docroot, and watch the log for requests to pages with unusual templates.
Check yourself
wp core versionTells you: the core release in use, against the table above
wp core verify-checksumsTells you: whether core files were edited by hand
find <docroot> -maxdepth 3 -type d -name 'page-*'Tells you: a page- directory in the theme — half of the condition
find /home -name '*.php' -readable 2>/dev/null | headTells you: readable PHP outside the docroot — the other half
wp theme list --status=activeTells you: the active theme; does it have a page- directory?
Sources
Written from the original advisory and the vendor's documentation; versions come from the site's data, updated 2026-11-10. Where they differ, the original advisory wins.