WordPress 7.1.2: Unauthenticated LFI to RCE in get_page_template() — Update Again
WordPress 7.1.2 (Sep 22, 2026) is a security-only release with one fix: CVE-2026-87902, CVSS 9.2, unauthenticated local file inclusion in page template resolution that reaches RCE where theme + PHP preconditions line up. Every version 4.7.0 through 7.1.1 is affected — including 7.1.1 from the Sep 17 Click2Shell release. Separate flaw, second emergency update, no workaround.
The bug: three lines apart
In wp-includes/template.php, get_page_template() builds candidate template names and hands them to the loader. One candidate comes from the pagename query var — raw request input:
// WordPress <= 7.1.1 (simplified, see Patchstack Sep 22, 2026)
if ( $template && 0 === validate_file( $template ) ) {
$templates[] = $template; // checked
}
if ( $pagename ) {
$pagename_decoded = urldecode( $pagename );
if ( $pagename_decoded !== $pagename ) {
$templates[] = "page-{$pagename_decoded}.php"; // NOT checked
}
$templates[] = "page-{$pagename}.php"; // NOT checked
}
The traversal guard existed on the line above and was missing on the pagename branch. The 7.1.2 fix adds validate_file() on the decoded value plus a new _wp_is_template_path_allowed() gate (reject .., else realpath() must resolve inside the theme directory). Single file changed: wp-includes/template.php.
Why RCE is conditional
The filename is assembled as page-{value}.php, so exploitation needs:
- Active parent/child theme with a top-level directory starting with
page-(e.g.page-templates). Legacy Twenty Twelve / Twenty Fourteen qualify, plus Neve, Hestia, Sydney per the GHSA. Current default themes do not. - A readable local
.phptarget — the known route is PEARpearcmd.phpwithregister_argc_argv=On(default on PHP < 8.5, officialphpDocker images, some cPanel defaults).
Check your fleet
# 1. am I on a fixed version?
wp core version
# need: 7.1.2 / 7.0.6 / 6.9.9 / 6.8.10 / 6.7.9 / 6.6.9 (or 4.7.37+ line)
# 2. does the active theme carry a page-* top-level dir?
THEME=$(wp option get stylesheet)
ls -d $(wp theme path $THEME)/page-* 2>/dev/null && echo "EXPOSED-SHAPE"
# 3. is the PHP precondition on?
php -i | grep -i register_argc_argv
# On => shrink it now (seatbelt, not fix):
# php.ini: register_argc_argv=Off (web SAPI), remove unused PEAR
Patchstack ships a RapidMitigate rule but still says update; researcher mitigations (argv off, drop PEAR) narrow the route without repairing the flaw. Ressl's PoC ran as the web-server user in local labs against 7.0.2 — no in-the-wild exploitation reported as of Sep 22, no CISA KEV entry.
Takeaway for builders: sanitize every branch, not just the first. The guard was three lines away and the missing call sat in the codebase for close to a decade of releases.
Originally published on WardenBit: https://wardenbit.com/posts/wordpress-712-unauthenticated-rce-update-again/?utm_source=devto&utm_medium=organic&utm_campaign=wordpress-712-unauthenticated-rce-update-again
Top comments (0)