Start trial

CVE-2026-87902: Attackers Started Probing WordPress Sites Hours After the Patch

Earlier today we wrote up CVE-2026-87902, the unauthenticated local file inclusion in WordPress page template resolution fixed in 7.1.2. That post covered the s

PublishedSeptember 22, 2026
Dave Jong avatar
Dave Jong
Security Research Lead at Patchstack

Earlier today we wrote up CVE-2026-87902, the unauthenticated local file inclusion in WordPress page template resolution fixed in 7.1.2. That post covered the sink, the preconditions and the fix. This is the follow-up, because the issue was already being probed in the wild before the day was over.

Patchstack customers are protected by a RapidMitigate rule. If you have not updated yet, WordPress 7.1.2 or the patched release on your branch remains the fix.

CVECVE-2026-87902
Vendor / ProductWordPress / WordPress Core
Vulnerability TypePath Traversal leading to Local File Inclusion and conditional RCE
CVSS9.2 (Critical)
Exploitation StatusActive probing observed
Authentication RequiredNo
Affected Versions4.7.0 to 7.1.1
Fixed Version7.1.2, 7.0.6, 6.9.9, 6.8.10 and backports to 4.7.37
First Observed Activity22 September 2026, 17:44 UTC

✌️ Our users are protected from this vulnerability. Are yours?

Web developers

Mitigate vulnerabilities in real-time without changing code.

See pricing
Plugin developers

Identify vulnerabilities in your plugins and get recommendations for fixes.

Request audit
Hosting companies

Protect your users, improve server health and earn additional revenue.

Patchstack for hosts

What We’re Seeing

The first probing attempts reached our logs at 17:44 UTC on 22 September 2026, less than five hours after 7.1.2 was published. The payloads match the exact encoding the patch addresses, so whoever built them was working from the diff rather than from an independent discovery. That turnaround is the main reason we are writing this up separately.

These Are Probes, Not Payload Delivery

This is worth being precise about. Every request we have seen so far points the inclusion at an ordinary WordPress core file:

wp-links-opml.php
wp-includes/functions.php
wp-cron.php

None of those give an attacker anything on their own. They are already part of a normal WordPress install and including them does not run attacker-controlled code. What they do give is a clear yes or no answer. wp-links-opml.php emits a distinctive OPML document, so if that comes back from a normal page URL the inclusion worked and the host is vulnerable. It is a cheap and reliable oracle.

So what we are looking at is the reconnaissance stage: someone building a list of which hosts are exploitable, not yet trying to execute anything. The step that actually matters, pointing the same primitive at something like pearcmd.php on a host with register_argc_argv enabled, has not shown up in our data yet. We would expect it to follow once the scanning results come back, and the targets are the thing to watch for change.

That gap is also the useful part for defenders. If you find these requests in your logs, they are probably a survey rather than a compromise. It is still worth checking what your server returned.

Two Details in the Requests

Defanged, a typical request has this shape. We are still not publishing a working one.

GET /?page_id=<valid page id>&pagename=templates%252f<traversal>wp-links-opml

The first detail is the double encoding. WordPress runs the slug through its own sanitiser before the template candidate is built, and that sanitiser deliberately preserves escaped octets while rewriting literal dots and truncating at literal slashes. A plain ../../ payload does not survive it. A percent-encoded one does, and then get_page_template() decodes it. That is why every request we have seen is double encoded at the HTTP layer, and it is what makes %252e%252e such a low noise thing to search your logs for.

The second detail is the page_id parameter, which appears in every single request alongside pagename. That is not padding. Without a page id that resolves to a real page, the query returns nothing, WordPress serves a 404, and the page template is never reached, so the vulnerable code never runs. Whoever wrote this understood the code path well enough to know the traversal alone is not sufficient. It also makes the pairing a good detection signal, since the two parameters rarely appear together in ordinary traffic.

Variations

The traffic is not a single fixed payload, so rules and log searches anchored too tightly on one string will miss things. What we have seen vary so far:

  • Traversal depth ranging from three to seven levels, presumably to cope with different theme and install layouts
  • Uppercase hex (%252F%252E%252E) as well as lowercase
  • POST as well as GET, which matters because WordPress reads pagename from the POST body in preference to the query string
  • Requests sent to /index.php directly as well as to the site root

All of them lead with templates%252f rather than starting with a traversal sequence, because the payload needs to continue a real directory beginning with page- before it can climb out of the theme. page-templates is the obvious guess and it is the one being used. A theme with a differently named page- directory would need a different prefix, so do not assume templates is the only one you will ever see.

Sources

The activity came from a small cluster of source addresses hitting multiple protected sites, with most of the volume concentrated in two neighbouring IPv4 addresses and some IPv6 traffic alongside it:

169.58.48.193
169.58.48.195
2001:df1:e8c0::106b

Most requests carried a Go-http-client/1.1 user agent, with a smaller share using spoofed browser strings. Activity peaked in the first hour and tapered off after that, which is the usual shape for an opportunistic sweep through a prepared host list rather than a targeted campaign.

Detection and Mitigation

Updating is still the answer. WordPress backported the fix as far as 4.7.37, so every affected branch has a patched release and an older site can take it without a major version jump. If you want to work out how exposed you are before you get there, the preconditions are in our original write-up: whether your active theme has a top-level page- directory, and whether your PHP has register_argc_argv enabled.

If you cannot update immediately, rejecting traversal sequences in the pagename parameter is an effective stopgap. A real page slug never contains one, so this can be blocked without affecting normal traffic.

For hunting through existing logs, the highest signal indicators are:

  • A pagename parameter containing %252e%252e, in the query string or the POST body
  • A pagename value beginning with templates%252f or another page- directory name
  • pagename and page_id appearing together on the site root or /index.php
  • OPML output, or any other unexpected core file output, returned from a normal page URL

That last one is the one that tells you whether a probe succeeded. A 200 response carrying OPML where a page should have been means the inclusion worked on your host, and you should treat it as a confirmed vulnerable window rather than a blocked attempt. Sites that were exposed before patching or mitigation should review historical logs on that basis, and check for unexpected or modified files while they are there.

We are continuing to monitor this, in particular for the shift from core file probes to inclusion targets that actually do something. If that changes we will update.

Timeline

22 September 2026WordPress 7.1.2 released and advisory GHSA-7hp8-65ch-5whp published.
22 September 2026Added to the Patchstack vulnerability database, with a RapidMitigate rule deployed to protected sites.
22 September 2026, 17:44 UTCFirst exploitation attempt observed and blocked.
22 September 2026, 19:51 UTCMost recent activity at time of writing.

🤝 You can help us make the Internet a safer place

Plugin developer?

Streamline your disclosure process to fix vulnerabilities faster and comply with CRA.

Get started for free
Hosting company?

Protect your users too! Improve server health and earn added revenue with proactive security.

Patchstack for hosts
Security researcher?

Report vulnerabilities to our gamified bug bounty program to earn monthly cash rewards.

Learn more

Like it? Share it.

Related articles