DEV Community

Hamza Ahmad Aslam
Hamza Ahmad Aslam

Posted on Originally published at hamzaahmadaslam.com

WordPress 7.1.4 security release: The updater flaw and what to do now

Originally published at hamzaahmadaslam.com.

How this article was made: drafted with AI assistance from a researched brief, then checked against primary documentation before publishing.

The WordPress 7.1.4 security release fixes 22 vulnerabilities, including an updater flaw that needs no login and could allow remote code execution. Wordfence has recorded attack attempts against the flaw. Check your WordPress version, block public access to the upgrade folder, and review your server logs.

What the WordPress 7.1.4 security release fixes

WordPress released version 7.1.4 on October 28, 2026. The release addresses 22 security vulnerabilities across 17 advisories, according to WordPress's version documentation.

The most concerning fix addresses a race condition in the core updater, reported by Umut Bayram. A race condition occurs when an outcome depends on which of two processes finishes first. Here, an attacker must reach temporary files while WordPress is updating.

Successful exploitation could lead to remote code execution (RCE), meaning an attacker runs code on your server without needing a WordPress account.

The remaining fixes cover several areas:

  • Contributor accounts can trigger stored cross-site scripting (XSS), unsafe Interactivity API bindings, prototype pollution, and browser denial of service. Many of these issues require a Contributor or higher account. Some also need another user to open malicious content.
  • Author accounts can trigger stored XSS in the Interactivity Router through uploaded text files.
  • Editor accounts can trigger stored XSS in the personal data erasure requests screen.
  • Other access problems include unpublished Customizer changes being exposed to visitors without accounts, a Notes API permissions flaw affecting certain custom roles, and multisite username handling.
  • Fixes without a stated role requirement include unsafe preg_replace() replacements in the Image and Playlist blocks, XSS in the Categories block, and post content shadowing Script Module data through a matching element ID.

The Customizer changeset disclosure also requires no login. The updater flaw stands out because successful exploitation can execute code on the server.

The release also updates bundled root certificates following the eMudhra revocation.

How the WordPress upgrade race condition works

During a full-package WordPress core update, the updater extracts downloaded files into a temporary directory under:

wp-content/upgrade/

Before the fix, that staging directory had a predictable name. It was also commonly reachable through the public web server.

The old cleanup process removed the directory's index.php guard, which normally prevents directory listings.

For a few seconds, the server could expose a temporary copy of WordPress. That copy included wp-admin/setup-config.php, the installer that starts without the site's existing configuration.

An attacker who requests the installer at the right moment can interact with the staged WordPress copy and progress to PHP code execution.

According to Patchstack's analysis, the patch makes three relevant changes:

  1. Adds 16 random characters to the temporary directory name.
  2. Recreates and preserves the index.php guard.
  3. Excludes wp-config.php from files copied out of the working directory.

The window exists during full-package core updates, including unattended updates. The attacker must reach the vulnerable files before the updater removes them.

Why an ordinary WordPress security plugin may miss it

The malicious request targets a PHP file inside the staged copy. It does not load the site's normal WordPress installation.

A security plugin that initializes through the site's usual WordPress loading process may never see that request.

Wordfence's Extended Protection mode is an exception because its firewall can initialize before the requested PHP file. A web application firewall (WAF) filters incoming HTTP requests.

A server-level rule denying public access to wp-content/upgrade/ removes this particular web entry point regardless of whether WordPress loads.

This updater flaw is separate from the July 2026 wp2shell vulnerabilities, CVE-2026-60137 and CVE-2026-63030.

How serious is CVE-2026-119977?

The WordPress GitHub advisory rates the updater issue Low and lists no known CVE.

Wordfence, acting as a CVE Numbering Authority (CNA), assigned CVE-2026-119977 and rated it 8.1, High, under CVSS 3.1.

CVSS is a standardized vulnerability severity scoring system. The Wordfence assessment includes AC:H, meaning high attack complexity.

Both assessments describe the same underlying flaw.

Wordfence emphasizes the potential impact of successful remote code execution. Patchstack also assigns high attack complexity but says it would not describe exploitation as practical.

That caution is based on the seconds-long window, the need for a full-package update, and the requirement that an attacker reach the staged installer in time.

What Wordfence observed

In its report, Wordfence states:

  • Its Premium, Care, and Response firewall rule went live on October 28 at 20:30 UTC.
  • The first matching request arrived nine minutes later.
  • During the first 21 hours, Wordfence recorded more than 18,500 requests targeting staged installer paths.
  • Two prominent sources repeatedly polled small groups of sites for roughly 14.5 hours.

Wordfence says some requests tested alternate directory layouts rather than exact vulnerable paths.

These figures measure requests and attempted exploitation. They do not establish successful code execution or the number of compromised sites.

The cited primary reports do not confirm successful compromises. That leaves the outcome of the observed attempts unknown.

Wordfence Free users are scheduled to receive the rule on November 27, 2026. Until then, free installations should not assume this particular rule is available.

Even with the rule installed, verify your core version and block the upgrade directory at the server.

Which WordPress versions contain the fix?

The WordPress security advisory lists the following patched versions. Each fixes the updater race within its corresponding branch.

WordPress branch Fixed release
7.1 7.1.4
7.0 7.0.8
6.9 6.9.11
6.8 6.8.12
6.7 6.7.11
6.6 6.6.11
6.5 6.5.14
6.4 6.4.14
6.3 6.3.14
6.2 6.2.15
6.1 6.1.16
6.0 6.0.18
5.9 5.9.20
5.8 5.8.19
5.7 5.7.21
5.6 5.6.23
5.5 5.5.24
5.4 5.4.25
5.3 5.3.27
5.2 5.2.30
5.1 5.1.28
5.0 5.0.31
4.9 4.9.35
4.8 4.8.34
4.7 4.7.39

WordPress explicitly states that version 4.6 and earlier no longer receive security updates.

The older releases are courtesy backports. WordPress says only its newest version is actively supported, so treat an older patched branch as a temporary measure while planning an upgrade.

Check one site

Open your WordPress dashboard and go to Dashboard > Updates.

Confirm that the installed version matches the fixed release for your branch. If it is older, arrange the security update.

If you have SSH access and WP-CLI installed, run this from the WordPress installation directory:

wp core version
Enter fullscreen mode Exit fullscreen mode

For a site in another directory:

wp core version --path=/var/www/example.com
Enter fullscreen mode Exit fullscreen mode

Replace the example path with your installation's filesystem path.

Check multiple sites

For sites accessible through the same server account, use a list of their installation directories:

for site in \
  /var/www/site-one \
  /var/www/site-two \
  /var/www/site-three
do
  printf '%s: ' "$site"
  wp core version --path="$site"
done
Enter fullscreen mode Exit fullscreen mode

Replace those paths with your actual installations. For separate servers, run the command over SSH on each server, or use WP-CLI's --ssh global parameter with configured remote access.

Each result must match the appropriate patched version in the table.

Multisite installations share the same WordPress core files. Check the network's core version, then audit individual site administrators separately.

Check automatic updates and disabled updates

WordPress says eligible installations begin automatic background updates. That does not guarantee a particular site completed the process successfully.

A failed download, filesystem permissions problem, hosting restriction, or intentionally disabled update can leave an older version installed.

If core updates are disabled, arrange a manual or host-managed update after applying the server-level block.

For managed hosting, ask the provider to confirm the installed build, successful completion, and the protection applied to temporary upgrade files. Request confirmation for every production environment, including staging sites reachable from the internet.

Block access to wp-content/upgrade before updating

If your site remains unpatched, establish the web-server restriction first.

The update to the fixed release may itself begin under vulnerable updater code. Blocking the directory beforehand reduces exposure during that final update.

Keep filesystem access available to WordPress. These rules block incoming web requests without preventing WordPress from writing temporary files.

Nginx configuration

Add the following location inside the relevant server block:

location = /wp-content/upgrade {
    return 403;
}

location ^~ /wp-content/upgrade/ {
    return 403;
}
Enter fullscreen mode Exit fullscreen mode

The ^~ prefix prevents a generic regex PHP location, such as location ~ \.php$, from taking precedence over requests within this directory. The exact-match location covers the directory path without a trailing slash.

For a subdirectory WordPress installation, adjust the URL prefix accordingly.

Use the Nginx location directive documentation when checking your existing configuration.

After editing, test the configuration and reload the server:

sudo nginx -t
sudo systemctl reload nginx
Enter fullscreen mode Exit fullscreen mode

These commands assume Nginx runs under systemd. Check with your provider if your server uses a different process manager.

Apache 2.4 and LiteSpeed using .htaccess

For an Apache installation using mod_rewrite, place this rule near the beginning of the site's root .htaccess, before WordPress's standard rewrite rules:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^wp-content/upgrade(?:/|$) - [F,END]
</IfModule>
Enter fullscreen mode Exit fullscreen mode

Apache's [F] flag denies access with HTTP 403. [END] ends further per-directory rewrite processing.

This example assumes WordPress sits at the site's URL root and that Apache permits rewrite rules through .htaccess. If mod_rewrite is unavailable, the rule inside IfModule will not apply.

For hosts that use LiteSpeed, confirm that their .htaccess implementation supports the rule and test the public response.

An alternative for Apache is a file named .htaccess inside wp-content/upgrade/:

Require all denied
Enter fullscreen mode Exit fullscreen mode

This requires Apache 2.4 authorization support and permission to use the directive in .htaccess.

The folder-local approach has a limitation: the old updater cleanup can delete files inside wp-content/upgrade/. Its restriction may disappear during the exact window you need to protect.

Prefer the root .htaccess rule or a restriction in the server's virtual host configuration. The root rule survives cleanup of the upgrade directory.

Refer to Apache's rewrite documentation when checking server permissions and rule behavior.

Confirm the block returns 403

After applying the rule, request a nonexistent PHP path beneath the protected directory:

curl -sS -o /dev/null -w '%{http_code}\n' \
  https://example.com/wp-content/upgrade/security-check.php
Enter fullscreen mode Exit fullscreen mode

Example output (illustrative):

403
Enter fullscreen mode Exit fullscreen mode

Replace the domain with your own.

A 404 response does not prove the rule works because the requested file does not exist. A 301 or 302 may indicate a redirect before the block is reached.

Test the final public hostname and any alternative route that reaches the origin server. If your CDN handles the request first, check that the origin also denies access.

Never create a PHP test file in the upgrade directory. The nonexistent path is sufficient to test a path-based denial rule when correctly configured.

Check access logs and WordPress for suspicious activity

Start with the server's access logs, which record incoming HTTP requests.

Review the period beginning before October 28 if your site was exposed or updated recently. Extend the review to include earlier full core updates if records are available.

Search access logs

On a server where the access log uses a conventional Nginx or Apache format, run:

grep -Ei '/wp-content/upgrade/[^ "]*\.php' \
  /var/log/nginx/access.log
Enter fullscreen mode Exit fullscreen mode

For Apache, substitute your actual access-log filename.

To search for installer requests anywhere:

grep -Ei '(/|%2f)setup-config\.php' \
  /var/log/nginx/access.log
Enter fullscreen mode Exit fullscreen mode

Check archived and rotated logs too. Depending on your host, these may be separate files or compressed archives.

Look closely at repeated requests, timestamp clusters around core updates, and paths containing wp-admin/setup-config.php below wp-content/upgrade/.

A request is evidence of probing. An HTTP 200 response deserves investigation, but a status code alone does not prove code execution.

The installer can also be requested during legitimate fresh installations. Compare suspicious entries with known maintenance activity.

Check for changes inside WordPress

List administrator users:

wp user list --role=administrator \
  --fields=ID,user_login,user_email,user_registered
Enter fullscreen mode Exit fullscreen mode

Review each administrator against your known team. For multisite, also check network super administrators in Network Admin.

List installed plugins:

wp plugin list
Enter fullscreen mode Exit fullscreen mode

Investigate unfamiliar plugins, particularly anything added around suspicious request times.

Search for PHP files in the temporary upgrade area:

find wp-content/upgrade -type f -name '*.php'
Enter fullscreen mode Exit fullscreen mode

Run this from your WordPress installation directory.

Unexpected PHP files elsewhere in writable directories also deserve review. Do not delete unfamiliar files before establishing whether they belong to a legitimate deployment or plugin.

Verify WordPress core checksums

Run:

wp core verify-checksums
Enter fullscreen mode Exit fullscreen mode

WP-CLI compares installed core files against the published checksums for the installed WordPress version.

A successful result means the checked core files match their expected contents. It does not prove that the rest of the site is clean.

A malicious plugin, altered theme, compromised user account, or additional file outside the checked core paths may remain undetected.

Investigate checksum mismatches. If the site uses a localized WordPress package, supply the appropriate locale when required.

Copy this checklist for each WordPress site

Record one copy per installation. Agencies should track the site hostname, hosting provider, and person responsible alongside it.

Check How to check Expected result Done
WordPress version Dashboard > Updates or wp core version Matches the fixed version for its branch [ ]
Server block Inspect Nginx or Apache configuration Public access to the upgrade directory is denied [ ]
HTTP 403 test Use the curl command above Returns 403 from the public hostname [ ]
Access logs Search for PHP requests under wp-content/upgrade/ No unexplained successful access or suspicious activity left uninvestigated [ ]
Administrator accounts Dashboard > Users or wp user list Every administrator is recognized and authorized [ ]
Plugin inventory Review installed plugins using WP-CLI Every installed plugin has a known purpose and owner [ ]
Core checksums Run wp core verify-checksums Core files verify, or every mismatch is explained [ ]

Save the evidence with the site's maintenance record. Record the installed version, the date of the HTTP test, and any log entries that need further investigation.

A clean checklist today does not establish whether an earlier compromise occurred. Limited log retention, deleted evidence, and changes outside core files can prevent detection.

What to do if your site is still vulnerable

If you find an unpatched version, apply the server restriction and verify that it returns 403. Then install the fixed release and confirm the installed version.

For WordPress 4.6 and earlier, arrange a migration to a maintained version. There is no corresponding security backport for those branches.

Keep the server restriction after updating. It limits unnecessary public access to temporary installation files during future updates.

For broader site protection beyond this issue, use the WordPress security hardening checklist.

If your review reveals an unknown administrator, unexplained PHP files, modified core files, or other convincing signs of compromise, preserve the relevant logs and begin a cleanup. The guide to cleaning a hacked WordPress site covers that process.

If you need help investigating or restoring a compromised installation, the WordPress malware removal service offers a free assessment followed by a fixed-price single-site cleanup.

Top comments (1)

Collapse
 
wbcomdesigns profile image
Wbcom Designs 💡 •

The point that a normal security plugin may never see the request is the part people will miss. The request hits the staged copy, not the site's WordPress, so "I have a firewall plugin" doesn't settle it. A server-level deny on wp-content/upgrade/ is cheap and doesn't depend on any plugin loading.

One thing to add for agencies: check every site's actual core version after auto-updates run. Sites with updates turned off, or pinned by a host, are the ones still sitting on the old updater.

Disclosure: we build WP Vanguard, which has a free no-signup scan that shows core version and exposed files. It's useful for a quick sweep across client sites: wpvanguard.com