Research/CVE-2026-87902
N-dayCVE-2026-87902CriticalPublic

CVE-2026-87902: WordPress, unauthenticated local file inclusion

get_page_template builds a page template name from the urldecoded pagename. locate_template concatenates it onto the theme directory. A classic theme with a page-templates directory includes a readable local PHP file.

Name
CVE-2026-87902: WordPress, unauthenticated local file inclusion
Type
N-day analysis
CVE
CVE-2026-87902
CVE Risk
critical
Disclosure Status
public
Vendor
WordPress
Affected
WordPress through 7.1.1. Patched in 7.1.2 and backported through 4.7.37.
Published
28 Oct 2026
Updated
28 Oct 2026
Tags
n-day, wordpress, lfi, cwe-98

WordPress, unauthenticated local file inclusion

WordPress Core 7.1.1 - WordPress

I am @abraxas_null. Loopback lab. The client is CVE-2026-87902-Abraxas-Labs.py.

Unauthenticated LFI via locate_template(). get_page_template() builds page-{$pagename}.php from urldecoded pagename. locate_template() concatenates onto the theme directory without a jail. Classic theme with a top-level page-* directory (page-templates). 7.1.2 adds _wp_is_template_path_allowed() and validate_file on the decoded pagename. Backported through 4.7.37.

CVE-2026-87902 (NVD). CWE-98. Vendor: WordPress. WordPress through 7.1.1. Patched in 7.1.2 and backported through 4.7.37.

What an attacker can do

GET a published page with double-encoded pagename walking out of the theme into a readable local .php. That file is included in the front-end response. Lab oracle is a witness PHP under uploads that also prints wp_version. Direct GET of the uploads file is not the bug (no wp_version). Not pearcmd.

How this showed up in the lab

I mapped template.php get_page_template + locate_template on 7.1.1, then a classic theme with page-templates, then a readable uploads PHP.

Control GET /?page_id=N must not contain the witness. Attack GET with double-encoded pagename must contain GHSA7HP8-WITNESS and wp_version=7.1.1.

Fail-controls already in the lab: witness only on a direct GET of the uploads PHP (wp_version=none); reverse shell; pearcmd.php gadget.

The lab

Port 18092. WordPress 7.1.1. Classic theme with page-templates. lab/witness.php planted under uploads. ./run.sh.

Target only 127.0.0.1:18092 (or the loopback you bound).

Plain text
cd lab
docker compose up --force-recreate
python3 ../CVE-2026-87902-Abraxas-Labs.py

Witness: Unauthenticated 200 body contains GHSA7HP8-WITNESS and wp_version=7.1.1. Control GET /?page_id=N does not.

References

CVE-2026-87902: WordPress, unauthenticated local file inclusion · Abraxas Labs