An Tran Solutions
An Tran Solutions
Back to Blog

WordPress Patched a Hole That Sat Quiet for Nearly 10 Years. The Reassuring Line in the Alert Is the Real Worry

September 23, 20265 min readby An Tran
On this page

For the past few days, a security alert has been making the rounds in WordPress groups and forums: critical vulnerability, CVSS 9.2, affects every version from 4.7.0 to 7.1.1, update now.

I'm going to say something I rarely get to say about this kind of news: that alert is right. Almost all of it. In a field where 90% of security news shared on social media is exaggerated or gets the numbers wrong, this one deserves credit.

But there's one line in it that's wrong. And ironically, it's the line that lets readers breathe out and push the update to next week:

"No real-world attacks have been observed so far."

That line is literally true. And it's the worst possible reason to wait. Let me explain with one specific timestamp.

What happened, in exact chronological order

Let's put each event on its actual date, because in security news, the order of events is the level of risk.

  • July 2026: researcher Robert Ressl privately reports the vulnerability via HackerOne (The Hacker News).
  • September 17, 2026: WordPress 7.1.1 ships with "17 bug fixes on Core, 19 bug fixes for the Block Editor, and 11 security fixes". This vulnerability is not among them (WordPress.org).
  • September 22, 2026: WordPress 7.1.2 is released with a single change: the fix for CVE-2026-87902 (WordPress.org).
  • September 22, 2026, 17:44 UTC: less than five hours after the patch is published, Patchstack's monitoring records the first probes (Patchstack).
  • Also on September 22: Hadrian publishes a working reproduction (PoC) demonstrating file access outside the theme directory (Hadrian).

Read those last two lines again. The patch and the first wave of scanning were less than an afternoon apart.

What the vulnerability actually is

In operator's language, not a security engineer's.

WordPress decides which theme file to use to render a page through the get_page_template() function in wp-includes/template.php. Patchstack describes the mistake very neatly: WordPress does check the path on one branch, but forgets the other: "The page template slug on the first line is passed through validate_file(), WordPress's own traversal check, before it's accepted. The candidate built from pagename never was." (Patchstack)

In plain English: two doors lead into the same room. WordPress put a lock on one, and left the other unlocked for almost ten years. The flaw affects the 4.7.0 to 7.1.1 range and is classified as CWE-98.

The attacker needs no account, no login and no upload. Just a carefully crafted URL carrying both the pagename and page_id parameters at the same time. Leave out either one and it doesn't work.

A note on the 9.2 score: the published CVSS scores don't agree. It's 9.2 according to Patchstack and The Hacker News, but 8.1 according to securityonline.info (CVSSv3 scale). That kind of gap between scoring systems is normal. Don't argue about the number. Both put it firmly in "deal with it now" territory.

What "no real-world attacks" means, and what it doesn't

This is the part I most want you to read carefully.

Patchstack says it outright: what they've seen so far is reconnaissance, not exploitation. Every request they logged targeted harmless WordPress core files (wp-links-opml.php, wp-includes/functions.php, wp-cron.php) as a test: if the contents of those files come back from an ordinary page URL, the site is vulnerable.

The probing traffic came from a small cluster: mainly two adjacent IPv4 addresses (169.58.48.193, 169.58.48.195), mostly with the user agent Go-http-client/1.1. The filter-evasion technique: double URL encoding (%252e%252e instead of ..), traversal depths of three to seven levels, over both GET and POST.

What do you see there? That's not an attack. That's market research. Someone is building a list of websites that qualify, to use later.

And here's the strategic point: the "no attacks yet" phase is not the time to relax. It's the only window in which you can still do something about it. By the time the news turns into "active exploitation observed", you're no longer reading the news. You're reading your own logs.

The alert included that line with good intentions, meaning "don't be complacent". But most readers only remember the first half.

Don't panic in the wrong place: having files read and losing the server are two different levels

To be fair and precise, because this is where the circulating alert blurs things a bit.

"Every version from 4.7.0 to 7.1.1 is affected" is true for the unauthorized file read (LFI). But to go further, to remote code execution (RCE), several more conditions have to stack up:

  1. The active theme must have a top-level directory whose name starts with page- (for example page-templates).
  2. PHP must have register_argc_argv enabled. Patchstack notes this setting "is on by default in the official PHP Docker images and in cPanel environments on PHP below 8.5".
  3. The server must have PEAR's pearcmd.php reachable.

The themes named: older default themes Twenty Twelve and Twenty Fourteen, plus some popular third-party themes such as Neve, Hestia and Sydney (securityonline.info).

Hadrian itself stresses the limits of the PoC it published: "Our reproduction confirms the traversal and inclusion behavior, not an RCE chain."

So the correct reading is: most websites face a file-leak risk. A smaller group faces the risk of losing the server entirely. The problem is: do you know which group you're in? If the answer is no, then in practice you have to behave as if you're in the second one.

And no, "we have auto-updates on" isn't an answer yet

This is the most common belief I want to challenge.

WordPress auto-updates really do work, and WordPress.org says clearly that sites with automatic background updates enabled will be updated. But three very common situations stop that from happening:

  • The site is on an old branch (6.6, 6.7, 6.8…). WordPress backported the fix to nearly every supported branch, 7.1.2, 7.0.6, 6.9.9, 6.8.10, 6.7.9, 6.6.9, all the way back to 4.7. Whether your site actually receives it is another matter.
  • Auto-updates are turned off. Very common on sites handed over by an agency, out of fear that an update will break the layout.
  • The file system is locked (DISALLOW_FILE_MODS) or the site is managed through Git or a deploy pipeline, so automatic updates technically can't run.

One more point: this patch arrived only five days after 7.1.1. If you updated last week and thought "just updated, nothing to worry about", that is exactly the trap.

And about the alert's line that "there is no other temporary workaround": there is, but it's only a band-aid. Patchstack describes a stopgap if you can't patch right away: block traversal sequences in the pagename parameter at the WAF level. It buys you time. It doesn't replace updating.

What to do, in this order

  1. Update today. Dashboard → Updates. If you're on an older branch, move to the patched release for that branch (7.0.6, 6.9.9, 6.8.10, 6.7.9, 6.6.9). Don't wait for the weekend.
  2. Confirm by version number, not by feel. Open /wp-admin → "At a Glance" and read the actual number. "It probably updated itself" is not confirmation.
  3. Check whether the active theme has any directory starting with page-. This structural condition decides which risk group you're in. One question for your technical team.
  4. Review your access logs. The clearest signs, according to Patchstack: a pagename parameter containing %252e%252e, a value starting with templates%252f, or pagename and page_id appearing together on the root URL. If you see them, you're already on the list.
  5. Sweep your "forgotten" sites. Old landing pages, staging copies, regional sites, last year's promotional microsite. These are always the first to be breached, because nobody remembers they still exist.

What I want you to take away isn't one CVE. Next year there'll be another.

What's worth remembering is the tempo: a flaw that sat quiet for almost ten years, patched in one day, and probed within five hours. The gap between "safe" and "on a target list" is no longer measured in weeks. It's measured in afternoons.

If your patching process today is "we'll get to it when we have time", then that process is the biggest vulnerability you have, not get_page_template().

Not sure which version your website is running, or who's responsible for updating it? Send us a message. A check takes fifteen minutes, and it's far cheaper than restoring a site that's been taken over.

Sources

Related articles