TRENDING
Five alphabetical thumb-index tabs cut into the edge of a dictionary, each labeled with a letter range
September 27, 2026
How to Build a Trie From Scratch in Python for Fast Prefix Search and Autocomplete
Five sample state-issued EBT benefit cards fanned out on a white background
September 27, 2026
AI-Made Fake Cards Turn an Old Mail Scam Into a Growing Fraud Wave
A real wooden outdoor sandbox filled with sand and toys, empty of people
September 27, 2026
OpenAI Pauses Training of Its Most Capable Models for the Second Time in Three Months
Subway turnstiles showing a green ENTER sign and a red DO NOT ENTER sign side by side
September 27, 2026
How to Verify Cloudflare Turnstile Tokens Server-Side in a Python App
Macro photo of a brass keyhole with a key partially inserted in a wooden door
September 27, 2026
TU Graz’s File Notification Attacks Turn a Decades-Old OS Feature Into a Side Channel
27 Sep 2026
SXZ.io SXZ.io
  • Home
Search the Site
Popular Searches:
Technology Amazon AI
Recent Posts
A green highway sign splitting into an EXPRESS lane and a LOCAL lane, the same express-lane idea a skip list uses to skip ahead through sorted data
How to Build a Skip List in Python to Get Balanced-Tree Speed Without the Rotations
September 27, 2026
Two well-worn paper archery targets riddled with arrow holes, mounted on cardboard backing at an outdoor range
Red Hat’s RHEL 10 STIG Update Turns Compliance Into a Moving Target
September 27, 2026
A manila file folder with a paperclip clipped to its tab, against a white background
CISA Orders Federal Agencies to Patch a SharePoint RCE Flaw Microsoft First Called Spoofing
September 27, 2026
SXZ.io SXZ.io
  • Home

Categories

Articles 210 Posts
News 211 Posts
Learning Hub 181 Posts
Home/News/WordPress 7.1.2 Patches an Unauthenticated File-Inclusion Bug That Reaches Back to 2016
News

WordPress 7.1.2 Patches an Unauthenticated File-Inclusion Bug That Reaches Back to 2016

WordPress 7.1.2 closes an unauthenticated local file inclusion bug in page template resolution that can reach remote code execution, present in WordPress Core since 2016.

September 22, 2026 5 Min Read
26

WordPress 7.1.2 shipped on September 22, 2026, and it fixes exactly one thing: an unauthenticated local file inclusion bug in page template resolution that can be chained into remote code execution. WordPress’s own security team calls it a critical severity vulnerability, and the code path it lives in has been part of WordPress Core since version 4.7.0, released in December 2016. No login is required to trigger it.

Table Of Content

  • The Bug Sat Three Lines Below Its Own Fix
  • What It Takes to Turn File Inclusion Into Code Execution
  • The Patch Does More Than Close the One Hole
  • A CVSS Score That Depends on Who’s Scoring It
  • Every Supported Branch Back to 2016 Gets the Fix
  • WordPress Core’s Third Critical Release in Two Months
  • What to Do

The bug, tracked as CVE-2026-87902, was reported to WordPress’s HackerOne-run bug bounty program by a researcher named Robert Ressl. It was fixed alongside a broader defensive change that WordPress’s team added on top of the specific patch, which is worth understanding on its own.

The Bug Sat Three Lines Below Its Own Fix

WordPress builds the list of candidate template files for a page inside get_page_template() in wp-includes/template.php. Security researchers at Patchstack, who published a technical breakdown the same day, laid out the vulnerable code:

// wp-includes/template.php, get_page_template(), WordPress <= 7.1.1
if ( $template && 0 === validate_file( $template ) ) {
    $templates[] = $template;
}

if ( $pagename ) {
    $pagename_decoded = urldecode( $pagename );
    if ( $pagename_decoded !== $pagename ) {
        $templates[] = "page-{$pagename_decoded}.php";
    }
    $templates[] = "page-{$pagename}.php";
}

Look at the two branches side by side. The first one runs the template slug through validate_file(), WordPress’s own directory-traversal check, before accepting it. The candidate built from the pagename query variable, three lines below, never gets that same check. The protection existed in the function; it just wasn’t applied everywhere it needed to be.

Two details shape what an attacker can actually reach with this. The filename is assembled as "page-{$pagename}.php", so a traversal payload has to continue a path that genuinely starts with page-, and the target still has to end in .php because the extension is hard-appended. That’s why the practical precondition is an active theme that ships a top-level directory starting with page-, something like a page-templates folder. According to the GitHub Security Advisory for the fix, that describes several themes still in real-world use, including Twenty Twelve, Twenty Fourteen, Neve, Hestia, and Sydney. The added urldecode() call on the pagename value is what turns an otherwise inert traversal-shaped slug into a real filesystem path once it’s decoded.

What It Takes to Turn File Inclusion Into Code Execution

Including a local PHP file isn’t, by itself, code execution of an attacker’s choosing. It runs whatever that file already does. Getting from inclusion to arbitrary code requires a readable .php file already sitting on the server that behaves usefully once included, and Patchstack points to the well-known candidate: PEAR’s pearcmd.php, which only becomes exploitable when PHP is running with register_argc_argv enabled. That setting is on by default in the official PHP Docker images and in cPanel environments running PHP versions below 8.5, which is a much larger share of real hosting than “unusual configuration” suggests.

Patchstack frames the honest version of this plainly: unauthenticated file inclusion happens every time the theme precondition is met, full code execution happens when the host environment also lines up. Enough hosts line up that the sensible default is to treat this as critical unless you’ve specifically checked your own stack and confirmed otherwise.

The Patch Does More Than Close the One Hole

WordPress shipped two changes in 7.1.2, not one. The first is the narrow fix: applying the same validate_file() check the sibling branch already had.

// wp-includes/template.php, WordPress 7.1.2
if ( $pagename_decoded !== $pagename && 0 === validate_file( $pagename_decoded ) ) {
    $templates[] = "page-{$pagename_decoded}.php";
}

The second change is broader, and it’s the more telling one. 7.1.2 also introduces a containment check that every resolved template path now has to pass, regardless of which code branch produced it:

// wp-includes/template.php, new in WordPress 7.1.2
function _wp_is_template_path_allowed( $path ) {
    global $wp_stylesheet_path, $wp_template_path;

    // A file path that exists and does not contain `..` is allowed.
    if ( 0 === preg_match( '#(?:^|/)\.\.[. ]*(?:/|$)#', wp_normalize_path( $path ) ) ) {
        return true;
    }

    // Otherwise resolve the real path and require it to sit inside an allowed theme directory.
    $real_path = realpath( $path );
    // ...
}

A one-line fix to the specific missing validate_file() call would have closed the reported bug. Adding a second, path-agnostic containment check on top of it signals that WordPress’s security team didn’t want to rely on catching every future asymmetry between sibling code branches by hand. Instead, any template path that resolves outside an allowed theme directory now gets rejected structurally, whichever function produced it.

A CVSS Score That Depends on Who’s Scoring It

The two organizations that scored this bug landed in different places. Patchstack’s own CVSS 4.0 vector rates it AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N, a base score of 9.2, with attack complexity marked low but attack requirements marked “present,” a CVSS 4.0-specific category for extra preconditions like the theme-and-gadget-file requirements above. The National Vulnerability Database‘s independent scoring, published the same day under the older CVSS 3.1 framework, comes out lower: AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H, a base score of 8.1. CVSS 3.1 has no separate slot for “attack requirements,” so the same real-world preconditions that CVSS 4.0 tracks explicitly end up folded into a high attack-complexity rating instead. Both frameworks still land on the same practical read: unauthenticated, network-reachable, and a full loss of confidentiality, integrity, and availability if it lands. WordPress’s own release notes independently describe it as a critical severity vulnerability without attaching a number to it.

Every Supported Branch Back to 2016 Gets the Fix

The vulnerable code has existed since WordPress 4.7.0, released in December 2016, through 7.1.1. That’s every WordPress Core release for close to a decade. Because WordPress still backports security fixes to every branch it supports, the GitHub Security Advisory lists a full column of patched point releases running from 4.7.37 up through the current 7.1.2, covering 4.8.32, 4.9.33, 5.0.29, and every minor version in between. An older site doesn’t need to jump to the latest major version to get the fix; the backport for its own branch will do it. WordPress’s own announcement notes that the courtesy backports to the oldest branches were still shipping as they become ready at the time of the release.

WordPress Core’s Third Critical Release in Two Months

This is the second security-only WordPress Core release in under a week and the third critical or high-severity Core patch since mid-July. WordPress 7.1.1 shipped four days earlier, on September 18, closing an unauthenticated comment cross-site scripting bug alongside the Click2Shell remote code execution chain that sxz.io covered at the time. Before that, 7.0.2 in July closed a separate critical pre-authentication RCE chain after a public proof-of-concept surfaced. None of the three share a root cause, but the pattern is the same each time: a small, structural mistake somewhere in Core that needed no account to trigger.

As of this release, there’s no public evidence of active exploitation. NVD’s own risk-assessment data for CVE-2026-87902 marks exploitation status as “none” as of publication. That’s a reason to move quickly, not a reason to wait: the bug requires no attacker account, and Patchstack deliberately withheld a working request precisely because comparing the patched and unpatched code side by side is enough for a capable attacker to reconstruct one.

What to Do

Update to WordPress 7.1.2, or to the patched point release for your branch, from the WordPress dashboard under Updates, or by downloading it directly from wordpress.org. Sites with automatic background updates enabled should already have received it. If you’re running an older default theme like Twenty Twelve or Twenty Fourteen, or a theme that ships its own page- prefixed template directory, treat the update as higher priority rather than lower: that’s exactly the precondition this bug needs.

Tags:

CVE-2026-87902PatchstackRemote Code ExecutionVulnerability ManagementWordPress Security

Share

Close-up of jumbled wooden letterpress printing type blocks in different letterforms and shapes
Previous Post

How to Build a Static Site Generator in Python From Scratch

A sea star with one visibly shorter, regenerating arm among its other full-length limbs, resting on a sandy tide pool floor
Next Post

Wordfence’s Mu-Plugin Discovery Turns a Blockchain Into a Takedown-Resistant Command Post

No Comment! Be the first one.

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Latest
27 Sep
How to Build a Skip List in Python to Get Balanced-Tree Speed Without the Rotations
27 Sep
Red Hat’s RHEL 10 STIG Update Turns Compliance Into a Moving Target
Trending
September 27, 2026
How to Build a Skip List in Python to Get Balanced-Tree Speed Without the Rotations
September 27, 2026
Red Hat’s RHEL 10 STIG Update Turns Compliance Into a Moving Target
September 27, 2026
CISA Orders Federal Agencies to Patch a SharePoint RCE Flaw Microsoft First Called Spoofing
September 26, 2026
How to Build a Trie From Scratch in Python for Fast Prefix Search and Autocomplete
September 26, 2026
AI-Made Fake Cards Turn an Old Mail Scam Into a Growing Fraud Wave
September 26, 2026
OpenAI Pauses Training of Its Most Capable Models for the Second Time in Three Months

Related Posts

Rows of server racks in a data center representing network infrastructure targeted by botnets
News

C0XMO Botnet Shows Why Old Router Firmware Still Matters

June 7, 2026
Close-up of a USB flash drive, representing physical data-theft risk in office security incidents
News

Fake IT Support Is Now Walking Through the Front Door

June 7, 2026
A phone security app on a smartphone resting on a laptop keyboard.
News

Everest Forms Pro Flaw Is Being Exploited to Create Rogue WordPress Admins

June 7, 2026
A phone secured by a padlock, illustrating AI data-leak containment and security controls.
News

OpenAI’s Lockdown Mode Is a Data-Leak Brake, Not a Prompt-Injection Cure

June 8, 2026
SXZ.io SXZ.io
  • [email protected]

Categories

Articles
Learning Hub
News

All Rights Reserved by SXZ.io ©2026