WordPress 7.1.4 is a security release, and the flaw it fixes is already being exploited in the wild. The uncomfortable part is that on an unpatched site, the update itself is the attack window: WordPress unpacks the new files into a folder inside your web root and finishes installing them while still running the old, vulnerable code. Two habits close that window — take a backup, and block web access to wp-content/upgrade before you click Update.
The flaw is CVE-2026-119977, a time-of-check to time-of-use race in WordPress’s core upgrade process. It affects versions 4.7 through 7.1.3. WordPress shipped the fix on October 28, and CISA has since added the flaw to its known-exploited list after confirming attacks in the wild; Wordfence said it blocked 13,095 attempts against it in a single 24-hour stretch. This is not a theoretical hardening post.
The short version
- CVE-2026-119977 can give an unauthenticated attacker code execution during a core update. It is fixed in WordPress 7.1.4.
- Versions 4.7 to 7.1.3 are affected, and the patch was backported to older branches, so check what you are actually running.
- Blocking
/wp-content/upgrade/at the web server kills the attack without stopping the updater. - Order matters: back up, block, update, verify. Blocking after the update is too late for that update.
- The plugin queue is bigger than the core queue — 549 plugin vulnerabilities were disclosed in a single week.
What the flaw actually does
When WordPress updates core with a full package, it downloads a complete copy of the new version and unpacks it into a temporary folder inside wp-content/upgrade/. That copy includes the installer. The folder lives under the web root, so the web server will happily serve files from it.
The temporary folder used to have a name an attacker could predict or find. So the sequence is: you start the update, WordPress writes the new files into a reachable folder, and an attacker who is polling for that folder loads the installer and completes an install before WordPress deletes the copy. That is code execution with no account and no password. The 7.1.4 fix gives the temporary folder a random name, so there is nothing left to guess.
Worth being honest about the shape of the risk: it is a narrow window and a high-complexity attack. It is not a drive-by. But narrow windows are exactly what automated scanners are built to hit, and “high complexity” stops meaning much when the scanning is free.
Who is actually exposed
- Sites on 4.7 to 7.1.3 that have not updated since October 28. That is the whole affected range, including old installs people forgot they own.
- Shared hosting, most of all. When WordPress cannot write core files directly, it falls back to the full-package upgrade — the exact code path this bug lives in.
- Anyone who turned off auto-updates and then stopped checking. Turning off auto-updates is a legitimate choice; turning off the calendar reminder that goes with it is not.
If you are already on 7.1.4 or newer, the flaw does not apply to you, but the habit still does. If your host patches for you, ask for the core version number rather than for reassurance — the answer is a version, not a feeling.
The five-minute update order
Do these in order. The block has to exist before the update runs, not after.
- Back up the database and the files. A database export plus a tarball of the site directory. If you have never restored one, test the restore before you need it.
- Block the upgrade folder at the web server. On nginx, add a location block that returns 403 for
^~ /wp-content/upgrade/. On Apache or LiteSpeed, add a rewrite rule in the site’s root.htaccess. This only refuses HTTP requests; PHP can still write to the folder, so the updater keeps working. - Update core. Dashboard → Updates → Update now, or from the command line with WP-CLI.
- Verify. Confirm the version, verify core checksums, then load the homepage and the login page while logged out.
- Leave the block in place. It costs nothing and closes the same trick in the next security release.
# 1. Back up before anything
wp db export ~/backup-$(date +%F).sql
tar czf ~/files-$(date +%F).tar.gz public_html
# 2. Block the upgrade folder (nginx), then reload nginx
# location ^~ /wp-content/upgrade/ { return 403; }
#
# Apache / LiteSpeed: put this above the WordPress block
# in the site root .htaccess:
# RewriteRule ^wp-content/upgrade/ - [F,L]
# 3. Update and verify
wp core update
wp core version
wp core verify-checksums
# 4. Plugin queue
wp plugin list --update=available
wp plugin update --all
If a host control panel runs updates for you and something breaks while the folder is blocked, remove the rule, run the update, and put it straight back. What you do not want is an update that starts, fails halfway, and leaves a half-unpacked copy sitting in a web-reachable directory while you go looking for the cause.
The plugin queue is bigger than the core queue
Wordfence’s weekly report for October 26 to November 1 counted 549 vulnerabilities across 351 plugins and 4 themes, including 17 critical and 132 high-severity disclosures. Forty-one had no patch at the time of disclosure. You cannot update your way out of those — the only move is to deactivate and delete.
A separate batch documented on November 9 covers 13 plugins, and four of them are common enough to check by name:
| Plugin | Installs | Problem | Action |
|---|---|---|---|
| LatePoint | 100,000 | Auth bypass, CVSS 9.1, through 5.7.6 | Update now |
| TranslatePress | 400,000 | Two stored XSS via comments, CVSS 7.2, through 3.3.8 | Update now |
| Amelia | 90,000 | SQL injection plus missing authorisation, CVSS 7.5, through 9.9.1 | Update now |
| wpForo | 20,000 | SQL injection and subscriber-to-admin escalation, CVSS 7.5, through 3.2.2 | Update now |
None of these plug straight into core, so they are not today’s headline. They are the reason “I updated WordPress” is not the same statement as “I patched my site”. A booking plugin with an authentication bypass is a worse day than a narrow core race condition, and it does not announce itself.
How to tell whether someone hit you during an update
Three checks, five minutes, no plugins required:
- Access logs. Search for requests to
/wp-content/upgrade/, especially POSTs to an installer file from an address that is not yours. Reading access logs is the same skill as spotting a brute-force run, pointed at a different string. - Administrator accounts. List the administrators and compare the registration dates against the day you ran the update. A new admin you did not create is the whole answer.
- Unexpected files. Anything ending in
.phpinside uploads, mu-plugins, or a leftover upgrade folder that you did not put there. This is part of the five-minute infection check.
If two of the three come back dirty, stop tidying and treat the site as compromised. Cleaning the symptom without finding the entry point is how a site gets reinfected a week later; the recovery order is: isolate, preserve evidence, rebuild from a known-good backup, then rotate every credential that touched the site.
The checklist I actually run
- Core version is 7.1.4 or newer on every site I am responsible for, including the one I forgot about in September.
/wp-content/upgrade/returns 403 from the public internet.- A backup from the last seven days exists, and one restore has been tested this year.
- No active plugin has a published, unpatched vulnerability — those get deleted, not “monitored”.
- Access logs checked for upgrade-folder requests in the last 30 days.
- One admin account per person who actually needs it, and nobody’s old developer still on the list.
None of this is exciting, which is the point. Sites rarely get hurt because the owner lacked a clever security stack. They get hurt because a three-week-old security release looked like a maintenance chore, and the update window stayed open while nobody was watching.

Leave a Reply