Safeguard
Supply Chain Security•

WordPress CVE-2026-119977 on KEV: Find Every Install, Patch to 7.1.4

CISA added WordPress Core CVE-2026-119977, an upgrade window race, to KEV on 3 Nov with a 6 Nov due date. Find every install, patch to 7.1.4, then triage.

Safeguard Security Team
31 min read

CVE-2026-119977 is a time-of-check time-of-use race condition (CWE-367) in WordPress Core 4.7.0 through 7.1.3 that can let an unauthenticated attacker run code on the server while a full-package core upgrade is in progress. CISA added it to the Known Exploited Vulnerabilities (KEV) catalog on 3 November 2026, due 6 November, with forensic triage required. Update every install to WordPress 7.1.4, then check past upgrade windows for compromise.

Key takeaways

  • KEV, with a three day clock. Added 3 November 2026, due 6 November, forensic triage "Yes", ransomware use "Unknown".
  • The fix already exists. WordPress 7.1.4 shipped on 28 October. Fixed releases exist for every branch back to 4.7 (7.0.8 down to 4.7.39). WordPress 4.6 and earlier get no fixes at all.
  • The bug lives in the upgrade itself. Before 7.1.4, core upgrades unpacked the new release into a predictable, web-reachable folder under wp-content/upgrade/. The exposure exists only while an upgrade runs.
  • The update to 7.1.4 passes through the window once more, on our reading of the code, because the unpack step runs on the old code. Add a web server deny rule for wp-content/upgrade/ first.
  • Containers need care. The official wordpress image copies WordPress into /var/www/html only when that folder is empty. A new image tag does not change files on an existing volume.
  • Patch, then triage, then gate. Check wp-content/upgrade/, wp-config.php, core checksums, admin users and web logs around past updates, and fail CI builds that carry an affected core.

What happened

On 28 October 2026 the WordPress project released WordPress 7.1.4, a security release. Among its fixes is "a weakness in the WordPress upgrade process which can lead to remote code execution during the upgrade window", reported by Umut Bayram. The 7.1.4 HelpHub page calls it "a race condition during core updates".

Wordfence, as the CVE Numbering Authority, published CVE-2026-119977 on 31 October under the title "WordPress Core 4.7.0 - 7.1.3 - Unauthenticated Upgrade-Window Staged-Installer Remote Code Execution". The description blames "predictable, web-accessible staging paths used during full-package core upgrades".

On 3 November CISA added it to KEV, the list of vulnerabilities with reliable evidence of exploitation in the wild. CISA's SSVC data in the CVE record says exploitation "active", automatable "no", technical impact "total".

So the fix came first, the CVE record three days later, and the exploitation listing six days after the release. Anyone who patched on 28 October was ahead of KEV.

It is also the fourth WordPress Core entry in KEV this year. The KEV feed (version 2026.11.03) lists CVE-2026-63030 and CVE-2026-60137 (21 July), CVE-2026-87902 (25 September) and now CVE-2026-119977. Before 2026, the only WordPress entries in KEV were plugins. Core is no longer the safe part of a site.

Timeline from primary sources

Date (UTC where published)EventSource
28 Oct 2026WordPress 7.1.4 and older branch fixes released; also the "Disclosed" date in the CVE recordWordPress.org; CVE record
30 Oct, 17:17CVE reservedCVE record
31 Oct, 05:33CVE record published by WordfenceCVE record
3 NovAdded to KEV; catalog 2026.11.03 released 20:00CISA KEV feed
3 Nov, 20:50CISA SSVC data addedCVE record, CISA ADP
6 NovKEV due dateCISA KEV feed
8 DecWordPress 7.2 plannedWordPress.org

What the KEV entry says

FieldValue
Vulnerability nameWordPress WordPress Core Time-of-check Time-of-use (TOCTOU) Race Condition Vulnerability
Date added / due date2026-11-03 / 2026-11-06
Known ransomware campaign useUnknown
Forensic triageYes
CWECWE-367

The required action is to apply mitigations per vendor instructions, in line with BOD 26-04 and CISA's "Forensics Triage Requirements", or discontinue use if mitigations are unavailable. The entry includes no indicators of compromise. CISA's guidance says it adds IOCs to a KEV entry when it has them, and as of 4 November this one has none, so the compromise checks below are built from what the fix changed, not from known attacker artefacts.

Why the forensic triage flag matters outside government

BOD 26-04, issued 10 June 2026, replaced BOD 22-01 and sets timelines from four factors: public exposure, KEV status, automatability and technical impact (our explainer). "& forensic triage" means remediating within three days and also checking the asset for compromise. The implementation guidance gives six steps: scoping, preserving and collecting evidence, patching, containment, triage analysis (unauthorized access, persistence, lateral movement, exfiltration) and an escalation decision, with target times inside 72 hours.

None of this binds a private company, but the order matters for WordPress: collect evidence before you patch, because the updater empties the folder you most want to inspect.

How the upgrade window works

This section stays at the level the public record supports and does not describe how to exploit the flaw.

What a full-package core upgrade does

Dashboard updates, background updates and wp core update all go through WordPress's upgrader classes (WP-CLI's CoreUpgrader extends WordPress's Core_Upgrader). In outline, the upgrader:

  1. Downloads the release zip to a temporary file.
  2. Empties wp-content/upgrade/.
  3. Creates a working folder there and unpacks the whole release into it.
  4. Enters maintenance mode and copies the new files over the live install, skipping wp-content and copying wp-includes/version.php last.
  5. Upgrades the database, removes the working folder and leaves maintenance mode.

Between steps 3 and 5, an unconfigured copy of a fresh release, installer scripts included, sits inside the web root. That is the upgrade window.

What was wrong before 7.1.4

In 7.1.3 the working folder was named after the package file, so its path was predictable, and because wp-content is web served, its files could be requested over HTTP while they existed. The CVE record references the unpack code in class-wp-upgrader.php, the core upgrader in class-core-upgrader.php, the copy routine in update-core.php and the installer's setup-config.php. Together with the "staged installer" title, the record describes a race between WordPress staging the release and using it, during which the staged copy was reachable.

The CVSS attack complexity is High because the attacker must hit a window that exists only during an upgrade. That is not comfort: background updates run on predictable schedules, and CISA has evidence of exploitation.

What 7.1.4 changed

The diff between tags 7.1.3 and 7.1.4 shows three upgrade changes:

  • Unpredictable folder name. A new get_working_dir_name() method appends a 16 character random string from wp_generate_password().
  • No directory listing. The upgrader creates wp-content/upgrade/index.php if missing and keeps it during cleanup, so the working folder "cannot be discovered from a directory index".
  • No planted config. update-core.php now skips wp-config.php when copying, with the comment "Never copy a wp-config.php, which could have been written to the working directory."

The last change tells defenders where to look: a wp-config.php in the working folder being copied over the live install is one outcome the fix guards against.

Why your next update is also a window

The unpack step runs on the upgrader you already have. When a 7.1.3 site updates itself to 7.1.4, the 7.1.3 code creates the predictable folder one last time. That is our reading of the code, not a statement from the WordPress project, and a one line server rule (below) closes it.

Affected and fixed versions

The CVE record lists the affected range per branch, the 7.1.4 HelpHub page lists the fixed release per branch, and WordPress.org's stable-check API marks every affected version "insecure". All three agree.

BranchAffectedFixed
7.17.1.0 to 7.1.37.1.4
7.07.0.0 to 7.0.77.0.8
6.96.9.0 to 6.9.106.9.11
6.86.8.0 to 6.8.116.8.12
6.76.7.0 to 6.7.106.7.11
6.66.6.0 to 6.6.106.6.11
6.56.5.0 to 6.5.136.5.14
6.46.4.0 to 6.4.136.4.14
6.36.3.0 to 6.3.136.3.14
6.26.2.0 to 6.2.146.2.15
6.16.1.0 to 6.1.156.1.16
6.06.0.0 to 6.0.176.0.18
5.95.9.0 to 5.9.195.9.20
5.85.8.0 to 5.8.185.8.19
5.75.7.0 to 5.7.205.7.21
5.65.6.0 to 5.6.225.6.23
5.55.5.0 to 5.5.235.5.24
5.45.4.0 to 5.4.245.4.25
5.35.3.0 to 5.3.265.3.27
5.25.2.0 to 5.2.295.2.30
5.15.1.0 to 5.1.275.1.28
5.05.0.0 to 5.0.305.0.31
4.94.9.0 to 4.9.344.9.35
4.84.8.0 to 4.8.334.8.34
4.74.7.0 to 4.7.384.7.39
4.6 and earlierNot in the CVE recordNo security updates
  • Backports are a courtesy. The release post still says the backports are "in progress", but the HelpHub pages for each branch (4.7.39 through 7.0.8) are live and dated 28 October, and the stable-check API lists those versions, as we checked on 4 November. The release post also says only the latest version is actively supported, and the older branches got fixes for fewer of the 22 issues in 7.1.4. Treat a backport as a first step toward 7.1.4.
  • 4.6 and earlier are a migration, not a patch. We do not claim they are affected by this CVE, but WordPress.org marks them insecure and fixes nothing there.
  • Trust roots changed too. 7.1.4 also updates the bundled root certificates after the eMudhra revocation (our explainer).

Technical details

ItemValueSource
CNA / finderWordfence / Umut BayramCVE record
CVSS 3.1 (CNA)8.1 High, CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:HCVE record; NVD
NVD statusUndergoing Analysis, no NVD score yetNVD API, 4 Nov
SSVC (CISA ADP)Exploitation active; automatable no; technical impact totalCVE record
Wordfence ID4b4da0cf-d9f4-47c4-a0e8-6c4dc5a6f250CVE record
wordpress-7.1.4.tar.gz SHA-1b175879c4fb2d35300f9abe1153da9b543a35a2bwordpress.org .sha1; pinned in the official Dockerfile
wordpress-7.1.4.zip SHA-1b552c39cd95d89895b4e7a55af53a03687aff4f6wordpress.org .sha1
wordpress-7.1.4.tar.gz SHA-256881e53a4681ff2cd911651b11cccdede5ae477ddf0765af5d6a1a8b219a1d835Computed by us, 4 Nov
wordpress-7.0.8.tar.gz SHA-1c0ed517c019c9b6412c4de8d59284acb1c0cdd94wordpress.org .sha1
7.1.4 version.php$wp_version = '7.1.4';, $wp_db_version = 61833;7.1.4 tarball
MD5, 7.1.4 wp-includes/version.php (en_US)edbd5ac8d5594b683ac972bcc0189661WordPress.org checksums API
MD5, 7.1.4 class-wp-upgrader.php (en_US)9f2b60bdae6094c78b791ab7ccbffd3eWordPress.org checksums API

Reading the vector metric by metric:

  • AV:N. Reachable over the network, through the site's own web server.
  • AC:H. The attacker has to act inside the upgrade window, which is short and only exists while an upgrade runs. This is the only metric holding the score below 9.
  • PR:N. No account on the site is needed.
  • UI:N. Nobody has to be tricked. An administrator clicking "Update Now" or a scheduled background update opens the window as part of normal operation.
  • S:U. The impact stays on the WordPress server.
  • C:H, I:H, A:H. Code execution on the server means full loss of confidentiality, integrity and availability for that site, and often for anything else that shares its database credentials.

The MD5 values are what wp core verify-checksums compares against, and they vary by locale.

As of 4 November, fixed artefacts exist in every main channel: WordPress.org offers 7.1.4 plus background updates from 7.0.8 down to 4.7.39; Docker Hub has wordpress:7.1.4 and its variants (we found no 7.0.8 or 6.9.11 tags, since the image follows the current release); and Packagist has 7.1.4 of roots/wordpress and johnpbloch/wordpress-core. For managed hosts and Linux distribution packages, ask the provider.

Who is exposed

  • Sites that update from the dashboard or by background update. They open the window every time core updates.
  • Containers on the official image with a persistent volume. After the first start, WordPress on the volume updates itself in place through the same upgrader, whatever image tag you pull.
  • Composer managed sites. Deploying from CI avoids the window, but the site stays vulnerable until the lock file moves, and an enabled dashboard updater can still open it.
  • Forgotten sites. Staging copies, microsites, intranets and agency sandboxes, often on old branches and unwatched.
  • Multisite networks. One core serves every site in the network, so one update fixes all of them, and one window exposed all of them.
  • Host managed sites. Many hosts roll core updates in waves for you. Confirm the version on each site and ask for update times and logs, because you will need both for triage.

Find every install

Use several views, because each misses something.

1. Repositories

# Composer managed core
grep -RIl --include=composer.lock -e '"roots/wordpress' -e '"johnpbloch/wordpress-core' . \
  | while read -r f; do
      echo "== $f"
      jq -r '.packages[] | select(.name|test("^(roots/wordpress|johnpbloch/wordpress-core)")) | "\(.name) \(.version)"' "$f"
    done

# Vendored core
find . -path '*/wp-includes/version.php' -not -path '*/node_modules/*' -exec grep -H "^\$wp_version" {} \;

# Official image references
grep -RInE --include='Dockerfile*' --include='*compose*.y*ml' '(FROM|image:)\s*(docker\.io/)?(library/)?wordpress(:|@|\s|$)' .

2. Container images

The official Dockerfile pins the version in a build step (version='7.1.4' plus the tarball SHA-1) and sets no version label or environment variable, so read the file.

# Core baked into an image
docker run --rm --entrypoint sh wordpress:7.1.3-apache \
  -c "grep '^\$wp_version' /usr/src/wordpress/wp-includes/version.php"

# Core a running container actually serves (the volume)
docker exec <container> grep '^\$wp_version' /var/www/html/wp-includes/version.php

# Kubernetes pods using WordPress images
kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{range .spec.containers[*]}{.image}{" "}{end}{"\n"}{end}' | grep -i wordpress

When the two disagree, the running container wins. For your own images, add an OCI label such as org.opencontainers.image.version with the core version.

3. Hosts

sudo find / -xdev -path '*/wp-includes/version.php' -not -path '*/wp-content/upgrade/*' 2>/dev/null \
  | while read -r f; do
      echo "$(grep -oP "^\\\$wp_version = '\K[^']+" "$f")  ${f%/wp-includes/version.php}"
    done | sort -V

4. WP-CLI and the stable-check API

wp core version --extra --path=/srv/www/example
wp @all core version                      # with aliases in wp-cli.yml
curl -s https://api.wordpress.org/core/stable-check/1.0/ | jq -r '."7.1.3"'   # insecure

5. SBOMs, and their gap

A Composer managed site has a package record for core. A site installed from a tarball or the official image has no package manager record of WordPress, so whether an SBOM lists core depends on the tool. Test with a known affected image before you rely on it. Our SBOM incident response guide covers the method. The generator meta tag and ver= query strings are often stripped by plugins, so do not use them as the inventory of record.

Patch and roll back

Collect evidence first

SITE=/var/www/html; STAMP=$(date -u +%Y%m%dT%H%M%SZ); OUT=/root/triage-$STAMP
mkdir -p "$OUT"
tar -czf "$OUT/files.tgz" -C "$SITE" .
wp db export "$OUT/db.sql" --path="$SITE"
cp -a /var/log/nginx /var/log/apache2 "$OUT/" 2>/dev/null || true
ls -la --time-style=full-iso "$SITE/wp-content/upgrade/" > "$OUT/upgrade-dir.txt" 2>&1
stat "$SITE/wp-config.php" > "$OUT/wp-config.stat"

The archive and export are also your rollback point.

Close the window for this update

The updater uses wp-content/upgrade/ through the file system, not over HTTP, so in our reading of the code a web deny rule does not get in its way. Test on staging.

location ^~ /wp-content/upgrade/ {
    deny all;
}
<Directory "/var/www/html/wp-content/upgrade">
    Require all denied
</Directory>

Do not put an .htaccess file inside wp-content/upgrade/: the pre-7.1.4 upgrader empties that folder when it starts. Without access to the virtual host, use RedirectMatch 403 ^/wp-content/upgrade/ in the root .htaccess (needs mod_alias). Keep the rule afterwards; nothing in that folder ever needs to reach a visitor.

Update the way the site is deployed

# WP-CLI
wp core update --path=/srv/www/example            # latest, 7.1.4
wp core update --minor --path=/srv/www/legacy     # stay on branch, e.g. 6.9.11
wp core update-db --path=/srv/www/example
wp core verify-checksums --path=/srv/www/example

# Composer
composer require roots/wordpress:7.1.4 --update-with-dependencies
  • Dashboard: Dashboard, Updates, "Update Now", with the deny rule in place.
  • Composer: commit the lock file, let CI run your tests, deploy. Files arrive from your build, so no upgrade window opens.
  • Official image: move to wordpress:7.1.4 (or a variant such as 7.1.4-php8.3-apache), then update the files on the volume in place with the deny rule active, or move to a layout where core comes from the image and only wp-content lives on the volume. Confirm with docker exec, not the tag.
  • Managed hosting: get the version and update time for each site in writing.

Roll back carefully

Rolling back core means returning to a vulnerable version. Do it only to restore service, keep the deny rule on, and fix forward fast. Prefer your pre-update archive; wp core update --version=7.1.3 --force is an emergency tool. A staging first update workflow prevents most rollbacks.

After the fix: check for signs of exploitation

CISA published no indicators, so these checks come from the mechanism and the fix. Run them on every site that was on an affected version and updated core while reachable from the internet.

1. List past upgrade windows

Use background update notification emails (WordPress sends them by default, and the background updates documentation shows the auto_core_update_send_email filter that can turn them off), deployment and WP-CLI history, hosting panel logs, and the timestamp of wp-includes/version.php, which the updater copies last.

2. Inspect wp-content/upgrade/

Between updates it should be empty, or hold only index.php on 7.1.4. Leftovers from failed updates can be innocent; a wp-config.php or unfamiliar .php file there is not.

find /var/www/html/wp-content/upgrade -mindepth 1 -printf '%TY-%Tm-%Td %TH:%TM  %p\n' | sort

3. Check wp-config.php

Compare it with your backup or configuration management, check its modification time against your windows, and read the database settings and any added code. A changed DB_HOST, unknown credentials or extra PHP mean escalate.

stat -c '%y %n' /var/www/html/wp-config.php
grep -nE "DB_(HOST|NAME|USER)|eval\(|base64_decode|include|require" /var/www/html/wp-config.php

4. Verify core and the web root

wp core verify-checksums compares core files with WordPress.org's checksums without loading WordPress; --include-root (WP-CLI 2.8.0 and later) also flags non-WordPress items in the root. It does not check wp-config.php or wp-content. See our verify-checksums guide.

wp core verify-checksums --include-root --path=/var/www/html

5. Accounts, settings and persistence

wp user list --role=administrator --fields=ID,user_login,user_email,user_registered --path=/var/www/html
wp option get siteurl --path=/var/www/html
wp cron event list --path=/var/www/html
ls -la /var/www/html/wp-content/mu-plugins 2>/dev/null
find /var/www/html/wp-content/uploads -type f -name '*.php'

Look for administrators created around a window, changed site URLs, unfamiliar cron events, unexpected must-use plugins and PHP in uploads.

6. Web logs around each window

Visitors never need anything from wp-content/upgrade/, so any external request there deserves a look, and a 200 deserves a close one. Successful requests to setup-config.php or install.php on a long installed site near a window are also worth review; scanners hit those paths constantly, so focus on 2xx responses.

zgrep -hE '"(GET|POST|HEAD) /wp-content/upgrade/' /var/log/nginx/access.log* | head -200
zgrep -hE '"(GET|POST) [^ ]*wp-admin/(setup-config|install)\.php' /var/log/nginx/access.log* | awk '$9 ~ /^2/' | head -200

Behind a CDN, its logs may hold the only source addresses.

7. If you find something

Isolate the site, keep the evidence, rotate the database password and salts (wp config shuffle-salts), reset administrator passwords, and rebuild from known good sources. Federal agencies report confirmed compromise to CISA; everyone else follows their own incident and notice duties.

Gate deploys on KEV-listed versions in CI

A small CI check stops an old lock file or base image from shipping an affected core again. Bash 4 or later:

#!/usr/bin/env bash
# wp-core-gate.sh: fail if any WordPress core under a path is below the fixed release for CVE-2026-119977
set -euo pipefail
declare -A FIXED=(
  [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
)
status=0
while IFS= read -r f; do
  v=$(sed -n "s/^\$wp_version = '\([^']*\)';.*/\1/p" "$f")
  branch=$(echo "$v" | cut -d. -f1,2)
  min="${FIXED[$branch]:-}"
  if [ -z "$min" ]; then echo "UNSUPPORTED  $v  $f"; status=1; continue; fi
  if [ "$(printf '%s\n%s\n' "$min" "$v" | sort -V | head -n1)" != "$min" ]; then
    echo "VULNERABLE   $v  $f  (needs $min or 7.1.4)"; status=1
  else
    echo "ok           $v  $f"
  fi
done < <(find "${1:-.}" -path '*/wp-includes/version.php' -not -path '*/wp-content/upgrade/*' -not -path '*/node_modules/*')
exit $status

Run it on the checkout and inside built images against /usr/src/wordpress. It also answers "am I affected?" for any directory tree. It covers one CVE; the durable version is a policy that blocks any KEV listed component, so the next WordPress Core entry needs no new script.

What would have helped

Practices any team can use

An inventory of record. The hard part this week is finding the 4.9 microsite and the forgotten staging copy. A list of every install with its version, deployment method and owner turns a three day deadline into a morning.

Deploy core from a build. Sites that receive core files from CI (Composer, an image, or a checksum verified tarball) never ran the upgrade inside the web root, and get a commit for every change. If you do this, switch off the in-site updater: AUTOMATIC_UPDATER_DISABLED stops background updates (background updates documentation) and DISALLOW_FILE_MODS blocks dashboard updates (wp-config documentation). Then make sure your pipeline ships security releases fast.

Do not serve folders nobody needs. In our view, a deny rule on wp-content/upgrade/ would have closed the web side of this flaw on any version.

Watch KEV, not just CVSS. An 8.1 with high attack complexity sits behind many 9s in a CVSS queue. KEV said it was exploited. See KEV as a WordPress vulnerability feed.

Know how your containers really update. The official image's volume behaviour is written in its entrypoint script, yet it surprises many teams. If WordPress updates itself on the volume, your image tags are not your inventory, and an image scan tells you what you shipped months ago rather than what is serving traffic today.

Keep logs long enough to triage. Seven days of web logs cannot answer questions about an update a month ago. Ninety days, stored off the server, is a sensible floor.

Where Safeguard fits

The fix for CVE-2026-119977 came from the WordPress project. Safeguard does not replace that release, your server configuration or your incident response, and Safeguard did not find this vulnerability. Where Safeguard helps is the work around the fix: knowing which projects and images carry an affected core, putting KEV listed vulnerabilities first, stopping builds that would ship an affected version, and keeping the record of what changed and when.

How Safeguard helps, step by step

Step 1: inventory sites and images

Safeguard's software composition analysis reads Composer projects, including composer.lock, and builds an SBOM per project, so a site pinning roots/wordpress or johnpbloch/wordpress-core carries the core version in its SBOM. Connect the site repositories, or scan a checkout or built image with the Safeguard CLI (safeguard scan --dir .), scan container images with Safeguard's container scanning, or use a local runner. For tarball and official image installs, test with a known affected image and keep checking version.php until you have confirmed what your SBOMs show.

Step 2: put KEV first

Safeguard shows CISA KEV status next to CVSS and EPSS for each vulnerability, so KEV listed CVEs sort ahead of ones that only score high. Reachability analysis is static and ranks findings by whether your code calls the vulnerable code. For a flaw in the platform's own upgrade process, KEV status and internet exposure are the useful signals; do not let a "not reachable" label delay a KEV listed platform patch.

Step 3: gate the build

Create a policy that fails any build whose SBOM contains a component with a KEV listed vulnerability, and attach it to a gate in CI. Gate actions can block, warn, notify or require approval. Once a site is on 7.1.4, an old lock file or a promoted staging branch fails the check instead of shipping. Keep the script above alongside it for tarball and image installs.

Step 4: open the fix, keep the evidence

For Composer managed sites, autonomous remediation can open a pull request moving core to 7.1.4. Pull requests are policy gated, your own CI runs the tests, and the feature ships switched off with every category set to Manual. SBOM history and gate results then show when each site moved, which is what an auditor or your triage report will ask for.

Open questions

Several things were not public as of 4 November, and they change how you should read the rest of this post.

  • Who is exploiting it, and how widely. CISA's KEV listing and SSVC "active" rating are the only public statements of exploitation we found. There is no public write-up of the attacks and no list of indicators. If CISA adds IOCs or entry specific triage guidance to the KEV entry, use it in place of the general checks above.
  • NVD's own score. NVD shows the record as "Undergoing Analysis", so the only CVSS score is the CNA's 8.1. NVD may publish its own assessment later.
  • Whether exploitation needed anything beyond the window. The public record describes the race and the staged installer. It does not say whether particular server configurations, such as directory listing being enabled or specific PHP handlers, made exploitation easier. Until that is clear, assume any affected site that updated core while reachable from the internet could have been exposed.
  • Distribution and host packages. Linux distributions and hosts that repackage WordPress follow their own schedules. Check each provider's advisory rather than assuming its package matches 7.1.4.

We will update this post if any of these change.

Common mistakes

  • Updating before collecting evidence. The updater empties wp-content/upgrade/ on every run.
  • Trusting the image tag. Read version.php inside the running container.
  • Putting the deny rule inside the upgrade folder. The old upgrader deletes it. Use the server config or the root .htaccess.
  • Stopping at the backport. It closes this CVE; 7.1.4 is the supported release.
  • Relying on verify-checksums alone. It skips wp-config.php and wp-content.
  • Reading AC:H as safe. Timing is hard, and CISA says someone managed it.

FAQ

Is CVE-2026-119977 being exploited?

Yes, according to CISA: it is in KEV, and CISA's SSVC data says exploitation is "active". As of 4 November we found no public write-up of the attacks, and the KEV entry lists no indicators. Ransomware use is "Unknown".

Does the 6 November due date apply to me?

It binds US federal civilian agencies under BOD 26-04. For everyone else it is a strong urgency signal, and customers, auditors and insurers increasingly ask how KEV entries are handled.

Which version fixes it?

WordPress 7.1.4, or the fixed release for your branch from the table above (7.0.8 down to 4.7.39).

Did automatic background updates already fix my site?

Possibly; WordPress.org offers the fixed releases as background updates. Check every site, because configuration, hosts and plugins can disable them, and remember that the update itself ran through one window on the old code. See whether WordPress core updates install themselves.

Does pulling the latest wordpress image fix my container?

Not by itself. The entrypoint copies WordPress into /var/www/html only when that folder has no index.php and no wp-includes/version.php. An existing install on a volume keeps its old core.

Is there a workaround if I cannot update today?

Deny web access to /wp-content/upgrade/ and hold off on core updates until you can do one properly. That is a mitigation and our suggestion, not the WordPress project's guidance.

Are plugin and theme updates affected?

The CVE covers full-package core upgrades, and we claim nothing beyond that. The new folder naming sits in the shared upgrader class, and the deny rule protects every kind of update anyway.

Did Safeguard find this vulnerability?

No. Umut Bayram reported it to WordPress, Wordfence published the CVE and CISA added it to KEV. Safeguard helps with inventory, prioritisation, gating and evidence around the fix.

Checklist before 6 November

  1. List every install: production, staging, microsites, intranets, agency and host managed.
  2. Record each version and how it is deployed.
  3. Collect evidence on affected sites: files, database, logs, wp-content/upgrade/, wp-config.php timestamps.
  4. Add the deny rule for /wp-content/upgrade/.
  5. Update to 7.1.4, or the branch fix as a first step.
  6. Confirm container versions with docker exec.
  7. Run checksums and the other compromise checks against every past window.
  8. Rotate credentials and salts wherever you find anything, and escalate.
  9. Add the CI gate.

Here the fix came from upstream fast: 7.1.4 and every backport shipped before the CVE record existed. What remains is finding every copy, getting the fixed version into production and proving it. The section below is our standard remediation playbook. Today the rows on a fixed version existing and on policies and gates apply; Gold Registry and fork and patch are for the next case, when a component you ship has no upstream fix at all.

Fix it without waiting for upstream

Whatever the vulnerability, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.

1. Autonomous remediation: pull requests, not tickets

When a fixed version exists, Griffin, Safeguard's security model, opens a policy gated pull request that moves the affected dependency to the safe version, and your own CI runs your tests on it before anyone merges. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation categories include dependencies, licenses, security posture and findings, and each one is set separately. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Auto-merge is a separate switch and stays off by default, so your team decides what merges on its own and what still needs a human approval.

2. Gold Open Source: the safe version in seconds, free

gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds.

3. Gold Registry: start from components that are already fixed

Safeguard Gold rebuilds patched versions of open-source packages and images from source, signs each build, attaches an SBOM, SLSA provenance and VEX, and serves them from registry.safeguard.sh to your organization. Every Gold artifact is held continuously to zero exploitable critical or high CVEs and a completed license check, with signed build provenance (signed with Safeguard's key and verifiable with cosign, SLSA Build Level 3 as the design target) and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.

When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened build of a specific package. Ask which packages it covers before you plan around it.

Your situationWhat to use
A fixed version existsAutonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version
You need to know today whether you are affectedGold Open Source lookup and "Am I affected?" checker, free and without login
You want vulnerable versions to stop shippingSafeguard policies and gates in CI
Upstream has no fix yet, or will not ship oneA custom Gold request; fork and patch
You want to start clean on new projectsPull hardened components and images from Gold Registry

One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.

See how Safeguard would help

The first demo is a real Safeguard CLI session. You install the CLI, run safeguard to open the interactive terminal and ask it to fix a lodash CVE in a repository. It reads the finding and the advisory, asks before any command that changes something, edits package.json to lodash 4.17.21, runs npm install and npm test with your approval, prints a summary and pushes nothing. The demo shows an npm change, not a WordPress one. For a Composer managed site you would make the same request against composer.json and composer.lock to move roots/wordpress to 7.1.4, then review the diff and run your tests before committing.

Click through it at your own pace, or open it full screen.

The second demo sets up the Safeguard runner on your own machine, approves it with its device code, then scans from the terminal. For an agency or platform team with many site repositories and images, that is how you run the inventory step from your own infrastructure.

Click through it at your own pace, or open it full screen.

The third demo connects Claude to the Safeguard MCP server with OAuth and lets you choose which tools Claude can use. Once connected, you can ask an assistant for a CVE's affected and fixed versions and KEV status while you plan. Whether a given CVE is in your workspace's data depends on your account, so confirm against the CVE record and the WordPress release notes.

Click through it at your own pace, or open it full screen.

To try it on your own sites and images, download Safeguard or start with the CLI documentation.

Quick check

Your container runs from the wordpress:7.1.4 image. Is it patched?

Not necessarily. If its volume already held an install, the entrypoint did not copy new files. Read /var/www/html/wp-includes/version.php with docker exec.

You updated a 7.1.3 site to 7.1.4 this morning with no deny rule. Anything left?

On our reading of the code, yes. That update ran through one last window on the old upgrader, and earlier updates did too. Run the compromise checks and add the deny rule.

A site runs WordPress 6.9.11. Does it need anything this week for CVE-2026-119977?

Not for the patch: 6.9.11 is the fixed release for the 6.9 branch. It still needs the triage checks for past update windows, and a plan to move to the supported 7.1 line.

Sources

Last reviewed: 4 November 2026. This is a developing story; check the linked advisories for the latest status.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

We email you a link to confirm, and only then add you to the list. Unsubscribe in one click. Privacy

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.