> CVE-2026-87902: how close is your WordPress to remote code execution?
[AUTHOR: Pierluigi Paganini]
[DATE: 23/09/2026 07:36]
[LANGUAGE: EN]
WordPress 7.1.2 fixes an unauthenticated file inclusion bug active since version 4.7, patchable but exploitable into remote code execution.
WordPress 7.1.2 shipped on September 22 address an unauthenticated local file inclusion, tracked as CVE-2026-87902 (CVSS score of 9.2), which stems of how the CMS resolves page templates, with a real path to remote code execution.
The bugs affected every version back to 4.7.0. That’s nearly a decade of releases, and nobody needs an account to trigger it. Robert Ressl gets credit for reporting it.
The flaw resides in get_page_template(), the function WordPress uses to choose which template should load a page. WordPress creates a list of possible template filenames, and one of them comes directly from the pagename value in the URL without any proper validation.
The problem becomes clearer when you look at the code around it. Just above the vulnerable line, WordPress uses validate_file() to check another filename and block directory traversal. But the filename built from pagename completely skips that security check, even though it sits only three lines below the protected code.
Getting from that gap to something dangerous takes a bit of luck, but not much. The filename gets built as page-{$pagename}.php, so the attacker needs a theme with a folder starting with page-, which plenty of legacy and third-party themes still have. A urldecode() call earlier in the process is what turns an otherwise harmless-looking string into a working traversal path.
Reading an arbitrary file isn’t code execution on its own. It only runs whatever that file already does. The well-known trick is pulling in PEAR’s pearcmd.php, and that only fires if PHP has register_argc_argv switched on, a setting that happens to be the default in the official PHP Docker images and in cPanel setups running anything older than PHP 8.5.
“Including a local .php file is not by itself code execution of the attacker’s choosing. It runs whatever that file does. Getting from there to arbitrary code needs a readable .php file on the server that behaves usefully when included, and the well-known candidate is PEAR’s pearcmd.php, which only becomes useful when PHP is running with register_argc_argv enabled.” reads the report published by the cybersecurity firm PatchStack. “That setting is on by default in the official PHP Docker images and in cPanel environments on PHP below 8.5, so “unusual configuration” undersells how common it is.
So the honest framing is a conditional chain: unauthenticated file inclusion always, code execution when the host happens to line up.”
So the honest way to describe this bug is a chain, not a single click. File inclusion works everywhere, no exceptions. Code execution only fires when the server’s setup happens to line up, and a lot of servers do.
WordPress’s fix does two things, and the second one is the more telling of the two. The obvious patch runs the missing validate_file() check on the pagename branch, closing exactly the hole that got reported. The less obvious one adds a new function, _wp_is_template_path_allowed(), that every resolved template path now has to pass, no matter which code path produced it.
The second change is also worth noting. A one-line fix would have addressed the reported bug, but WordPress instead added a broader check across the template system. That suggests the security team wanted to make sure there were no other ways to reach the same problem.
If you cannot patch right away, two quick checks can help you understand your exposure. First, see if your active theme contains a folder starting with page-. Then check whether PHP has register_argc_argv enabled. Neither is a fix, but both can help show whether your site could be affected.
Updating is simple enough that there’s no good excuse left. It’s sitting in the Dashboard under Updates, or on WordPress.org directly, and every supported branch back to 4.7 already has its own backported fix waiting.
“Treat it as critical unless you have checked your own stack and know otherwise.” concludes Patchstack.
Follow me on Twitter: @securityaffairs and Facebook and Mastodon
Pierluigi Paganini
(SecurityAffairs – hacking, WordPress)