DEV Community

Cover image for WordPress 7.1.2: Unauthenticated LFI to RCE in get_page_template() — Update Again
Stanley A.
Stanley A.

Posted on Originally published at wardenbit.com

WordPress 7.1.2: Unauthenticated LFI to RCE in get_page_template() — Update Again

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
}
Enter fullscreen mode Exit fullscreen mode

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:

  1. 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.
  2. A readable local .php target — the known route is PEAR pearcmd.php with register_argc_argv=On (default on PHP < 8.5, official php Docker 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
Enter fullscreen mode Exit fullscreen mode

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)