In late October 2026, a vulnerability was found in the WordPress update mechanism: CVE-2026-119977. It allows an attacker with no login or password to execute arbitrary code on the server — but only while the site is updating. The vulnerability is already being used in real attacks.
Below is how it works, who is affected and what to do to protect your site.
The vulnerability in brief
- What it is: a race condition (TOCTOU class) in the full WordPress core update process.
- Severity: CVSS 8.1 (High).
- Affected versions: WordPress 4.7 through 7.1.3 inclusive.
- What the attacker needs: only HTTP access to the site. No authentication and no administrator action required.
- Exploitation: on November 3, 2026, CISA added the vulnerability to its Known Exploited Vulnerabilities (KEV) catalog. Wordfence recorded more than 18,500 requests to the vulnerable paths in the first 21 hours after the details were disclosed.
How the attack works
During a full core update, WordPress does the following:
- Downloads the archive with the new version.
- Extracts it to a temporary folder inside
wp-content/upgrade/. - Copies the files over the live site.
- Deletes the temporary folder.
The problem is that the temporary folder sits at a predictable path and is reachable from a browser. Inside it is a complete copy of WordPress, including the setup-config.php installer.
While the update is running, the attacker can open this installer and go through it. As a result, they can replace the live wp-config.php and point the site at their own empty database. WordPress then offers an "installation" — the attacker completes it, becomes an administrator and runs their own PHP code on the server.
The attack window is the few seconds the update takes. That makes the attack hard to pull off in practice, but mass scanners probe the vulnerable paths constantly, counting on exactly that timing to line up.
Version 7.1.4 randomizes the temporary folder name, adds protection against direct access and blocks configuration from being carried over from the temporary copy.
Timeline
| Date | Event |
|---|---|
| October 28, 2026 | WordPress 7.1.4 and fixed releases for older branches are published |
| October 30, 2026 | First exploitation attempts are recorded |
| October 31, 2026 | The vulnerability is assigned CVE-2026-119977 |
| November 3, 2026 | CISA adds the vulnerability to the KEV catalog |
Fixed versions
The fix has been backported to every supported branch down to 4.7. We recommend updating to the latest version, 7.1.4.
| Branch | Fixed version |
|---|---|
| 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.x, 4.7–4.9 | A fixed release for each branch, down to 4.7.39 |
Versions 4.6 and older did not receive a fix. These sites need to be updated to a current version or taken out of service.
Step 1. Check your WordPress version
In the admin panel: Dashboard → Updates. Do not rely on automatic updates — they may not have run: they could be disabled, fail because of file permissions or be overridden by a plugin.
With WP-CLI:
wp core version
If you have several sites on the server, you can find every WordPress installation and its version like this:
find /var/www -path '*/wp-includes/version.php' -exec grep -H "wp_version =" {} \;
Replace /var/www with the directory where your sites live.
Step 2. Block access to wp-content/upgrade/ (for VPS and dedicated servers)
This is the most important measure. It closes the attack window regardless of your WordPress version and does not interfere with updates: WordPress works with this folder through the file system, not over the web. Do this before updating, since the attack happens precisely during the update.
nginx
Add this to your site's server block:
location ^~ /wp-content/upgrade/ {
deny all;
}
Test the configuration and reload nginx:
nginx -t && systemctl reload nginx
Apache and LiteSpeed
Add this to the .htaccess file in the site root, above the standard # BEGIN WordPress block:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^wp-content/upgrade/ - [F,L]
</IfModule>
If you have access to the Apache virtual host configuration, it is more reliable to block the directory there:
<Directory "/var/www/example.com/wp-content/upgrade">
Require all denied
</Directory>
Replace the path with your own and reload Apache:
apachectl configtest && systemctl reload apache2
On AlmaLinux, Rocky and other RHEL-based systems, the service is called httpd.
Check that the block works
curl -I https://example.com/wp-content/upgrade/
The response should return code 403.
Step 3. Make a backup
Before updating, back up the site files and database. With WP-CLI:
wp db export ~/backup-$(date +%F).sql
tar -czf ~/site-files-$(date +%F).tar.gz -C /var/www/example.com .
If you have a VPS, you can also take a server snapshot in the control panel.
Step 4. Update WordPress
Through the admin panel or WP-CLI
If you have blocked access to wp-content/upgrade/ (Step 2), update as usual — from the admin panel or with WP-CLI:
wp core update
wp core update-db
wp core version
The last command should show 7.1.4 or the fixed version for your branch.
Manually, with no attack window
If you cannot block access to the directory at the web server level (for example, you have no access to its configuration), it is safer to update manually. The archive is extracted outside the site root, and the files are copied over without touching wp-config.php or wp-content:
cd /tmp
wget https://wordpress.org/latest.tar.gz
tar -xzf latest.tar.gz
rsync -a --exclude 'wp-content' --exclude 'wp-config.php' /tmp/wordpress/ /var/www/example.com/
rm -rf /tmp/wordpress /tmp/latest.tar.gz
Then restore the file ownership (the web server user may differ, for example nginx or apache) and update the database:
chown -R www-data:www-data /var/www/example.com
wp core update-db
Instead of the last command, you can open https://example.com/wp-admin/upgrade.php in your browser.
Don't forget plugins and themes
wp plugin update --all
wp theme update --all
Step 5. Check your site for signs of compromise
If your site was updated from a vulnerable version after October 28, make sure nobody took advantage of the attack.
Requests to temporary installers in the logs:
# nginx
grep -E "wp-content/upgrade/.*\.php" /var/log/nginx/access.log*
# Apache
grep -E "wp-content/upgrade/.*\.php" /var/log/apache2/access.log*
Requests with a 200 response code are especially suspicious.
A replaced wp-config.php: check the file's modification date and the database connection settings.
ls -l /var/www/example.com/wp-config.php
grep -E "DB_(NAME|USER|HOST)" /var/www/example.com/wp-config.php
Core file integrity:
wp core verify-checksums
Unfamiliar PHP files and administrators:
find /var/www/example.com/wp-content/upgrade /var/www/example.com/wp-content/uploads -name "*.php"
find /var/www/example.com -name "*.php" -mtime -10
wp user list --role=administrator
If you find a replaced wp-config.php, unfamiliar administrators or unexpected PHP files, treat the site as compromised. Restore it from a backup made before October 28, update WordPress and change all passwords: administrator, database, FTP and SSH.
If a contractor maintains your site
Forward this article to them and ask them to confirm that the site has been updated to a fixed version and checked for signs of compromise.
Need help?
Not sure you can handle this yourself, or found suspicious files? Contact our support team — we will help you sort it out.