Home/ Blog/ Security news/ Article
Blog · Security news

WordPress CVE-2026-119977: Upgrade-Window RCE Probed, Update to 7.1.4

WordPress CVE-2026-119977 lets unauthenticated attackers run code during a core update. Versions 4.7 to 7.1.3 are affected; update to 7.1.4 and check your logs.

Dark gradient cover reading WordPress updates open a brief code-execution window

The riskiest moment for a WordPress site this week is the moment it updates. CVE-2026-119977 lets an attacker with no account run PHP code on the server, but only during the few seconds a full-package core upgrade is being unpacked. Attackers are already polling for those seconds: Wordfence counted more than 18,500 requests aimed at staged installer paths in the first 21 hours after WordPress 7.1.4 shipped on October 28. Update to 7.1.4 or your branch's backport, stop PHP from executing in the upgrade staging folder, and read your access logs from October 28 forward.

The flaw received its CVE ID only this morning, October 31, three days after the patch. Wordfence, which assigned it, scores it CVSS 8.1 (High). WordPress's own GitHub security advisory for the same bug, GHSA-4w3m-c66w-69mg, labels it Low. Both readings hold up, and the gap between them explains how attackers are going after it.

How does CVE-2026-119977 work?

CVE-2026-119977 is a time-of-check to time-of-use race condition in the WordPress core updater. When a full-package core upgrade runs, versions 4.7 through 7.1.3 extract the new release into a folder under wp-content/upgrade with a guessable name, and the web server will serve it. That temporary copy includes the WordPress installer, which an unauthenticated visitor can reach and use to get PHP code running.

Alex Thomas, who leads Wordfence's Threat Response Team, described the path to The Hacker News: request the staged installer at the right moment, interact with that copy of WordPress, and progress to code execution. The request hits the staged PHP file directly, so the live WordPress install never loads to inspect it. That is why Wordfence tells its users to turn on the firewall's Extended Protection mode, which runs before WordPress does.

The German WordPress magazine Dr. Web diffed 7.1.3 against 7.1.4 and found the fix in two places. The staging folder now carries a random 16-character suffix plus an index.php guard, and the updater no longer promotes a wp-config.php found in the working folder into the site root, where it would execute on every page load.

Why WordPress calls it Low and Wordfence calls it High

Four conditions have to line up. A full-package update must be running, the staging tree must be reachable over the web with PHP enabled, the attacker must know or guess the path, and the request must land before WordPress deletes the temporary files. In Wordfence's lab that window lasted seconds. The CVSS vector reflects this with a high attack-complexity rating, and it is why the WordPress security team could reasonably file it as Low.

Our read: the Low rating describes one site, and the High rating describes the internet. Sites with automatic background updates pull a new core within hours of each release, so across millions of installs there is almost always someone unpacking. An attacker does not need to win a particular race, just some of them. Wordfence's telemetry fits that strategy. Its two largest sources kept polling small groups of sites for roughly 14.5 hours, while others cycled through staging-folder and version-name guesses. That is the behavior of someone waiting for an update to start, not someone expecting the first request to work.

The patch that delivers the fix may open the window

Here is the uncomfortable part. The download and unpack step is run by the updater code a site already has installed. By our reading of the files the fix changed, that means the upgrade to 7.1.4 itself goes through the old, predictable staging logic whenever WordPress fetches a full package. The fix protects the next update, not necessarily the one carrying it.

Timing makes this concrete. According to the Wordfence write-up, its firewall rule reached paying customers at 20:30 UTC on October 28, about three hours after the release, and caught its first match nine minutes later. Sites that auto-updated that evening were doing so while probes were already arriving.

None of this is a reason to delay the update. It is a reason to start your log review at the release, not at the moment each site finished patching, and to block the staging folder from the web on hosts where you trigger updates yourself.

Which WordPress versions fix CVE-2026-119977?

WordPress 7.1.4 is the fixed release, and the GitHub advisory lists a patched build for every branch back to 4.7, ending with 4.7.39. WordPress said on release day that older-branch backports would ship as they became ready, so confirm the exact build each site reports under Dashboard, Updates rather than assuming the background update landed.

BranchLast vulnerable buildFixed build
7.17.1.37.1.4
7.07.0.77.0.8
6.96.9.106.9.11
6.86.8.116.8.12
6.76.7.106.7.11
6.66.6.106.6.11
6.56.5.136.5.14
4.74.7.384.7.39
Source: WordPress GitHub advisory GHSA-4w3m-c66w-69mg. Every branch between 4.7 and 6.5 also has a patched build.

In plain terms: 7.1 sites need 7.1.4, 7.0 sites need 7.0.8, 6.9 sites need 6.9.11, and the oldest supported branch needs 4.7.39. WordPress 4.6 and earlier receive no security updates, so those installs stay exposed on every future core update.

Hunt the staging path in your access logs

Normal visitors and crawlers have no reason to request a PHP file under wp-content/upgrade. WordPress writes to that folder through the filesystem, not over HTTP. Any such request in your logs since October 28 is a probe at minimum. The response code tells you how far it got: a 404 means the attacker missed the window, while a 200 on a staged setup-config.php means the request reached live installer code and the site needs a closer look.

Access-log hunt: PHP requests into the core upgrade staging folder
grep -hE '"(GET|POST|HEAD) [^" ]*/wp-content/upgrade/[^" ]*\.php' \
  /var/log/nginx/access.log* \
  /var/log/apache2/access.log* \
  /var/log/httpd/access_log* \
  /usr/local/apache/domlogs/* 2>/dev/null
ls -la /path/to/site/wp-content/upgrade/

Adjust the log paths for your stack; the pattern is the part that matters. If you find a 200, follow Wordfence's checklist: look for administrator accounts nobody created, plugins nobody installed, and PHP files nobody placed. With WP-CLI, wp user list --role=administrator and wp core verify-checksums cover the first and third quickly. Outside an update in progress, the staging folder should hold nothing you cannot explain.

Deny PHP in the staging folder before the next update

Updating is the fix. The extra step is for hosts that are still on a pre-7.1.4 build and for every core update those hosts run until they are current: tell the web server never to execute PHP inside wp-content/upgrade. On Nginx, that is a location block matching ^/wp-content/upgrade/.*\.php$ with deny all;. On Apache or LiteSpeed, use an equivalent Directory or FilesMatch rule in the virtual host configuration rather than a file inside the folder the updater manages. Because the updater moves files without going through the web server, the rule should not interfere with updates, but test it on one site before you roll it out.

If you host many WordPress accounts, a server-level rule covers all of them at once, including the sites whose owners never log in. According to Wordfence, sites that rely on its free plugin will not receive the firewall rule for this flaw until November 27, a month after the patch, so they should not wait for it.

The third core code-execution flaw since July

This is the third unauthenticated WordPress core code-execution bug we have covered since July, after wp2shell (CVE-2026-63030) and CVE-2026-87902, which, like this one, reached back to 4.7. The same 7.1.4 release also swapped bundled root certificates after the eMudhra revocation we covered in the Java trust-store post. For anyone running a WordPress fleet, the inventory is the control that matters: which installs exist, which branch each one runs, and whether background updates actually complete. File integrity monitoring on webroots is how you find out about the update that did not. The next core bug will reach back just as far, and the sites that get hit will be the ones nobody remembered to count.

Topics

Frequently asked questions

What is CVE-2026-119977?

CVE-2026-119977 is a race condition in the WordPress core updater that lets an unauthenticated attacker run PHP code during a full-package core upgrade. It affects WordPress 4.7 through 7.1.3, carries a CVSS score of 8.1 from Wordfence, and is fixed in WordPress 7.1.4 and its branch backports.

Is CVE-2026-119977 being exploited?

Attackers are attempting it. Wordfence recorded more than 18,500 requests to staged installer paths in the first 21 hours after the October 28 patch, with a first firewall match nine minutes after its rule went live. As of October 30, no successful compromise had been publicly confirmed.

Which WordPress versions fix CVE-2026-119977?

WordPress 7.1.4 fixes it, and WordPress's GitHub advisory lists backports such as 7.0.8, 6.9.11, 6.8.12 and 4.7.39 for older branches. Check the exact build each site reports under Dashboard, Updates, because older-branch backports were still shipping after release day.

Why does WordPress rate it Low when its CVSS score is 8.1?

WordPress's advisory labels it Low because exploitation needs a full-package update in progress, a web-reachable staging folder and a request that lands within seconds. Wordfence scores it 8.1 because, when those conditions line up, an attacker with no account gets code execution on the server.

How do I check whether my WordPress site was targeted?

Search web server access logs from October 28 onward for any request to a PHP file under wp-content/upgrade, which normal traffic never requests. If any returned HTTP 200, check for new administrator accounts, unfamiliar plugins and PHP files you did not place, and verify core file checksums.

Does blocking PHP in wp-content/upgrade break WordPress updates?

It should not. The core updater writes and moves files in that folder through the filesystem rather than over HTTP, so denying web execution of PHP there removes only the attack path. Test the rule on one site before rolling it out, and still update to the fixed release.

See what Suriq finds on your own servers.

Agentless checks for uptime and your cloud, a lightweight agent for detection on each server, and one console that ranks and explains what it finds.