WordPress 7.1.4 Closes an Unauthenticated Race in Its Own Update Routine, but 19 Older Branches Had No Backport Three Hours After Release
WordPress 7.1.4 fixes 22 vulnerabilities by WordPress’s count, including an unauthenticated race in its updater, but three hours after release the HelpHub page listed backports for 19 older branches...
WordPress 7.1.4, released on October 28, fixes 22 vulnerabilities by WordPress’s own count, among them a race in the core update routine that Patchstack lists as needing no account. The new code gives the update’s working folder a random 16-character suffix, stops deleting the index.php that keeps the folder from being listed, and never copies a wp-config.php out of it. Sites on the 7.1 branch are offered the update automatically. The gap is older branches. WordPress’s HelpHub page says the fixed version for every branch down to 4.7 “has been released containing fixes,” and Patchstack repeats that list, but the release post says the backports “are in progress and will ship as they become ready.” At 19:34 UTC, 3 hours 17 minutes after the 7.1.4 zip appeared, WordPress.org’s download servers, releases page and update API showed new releases for six branches (7.1 down to 6.6) and none for the 19 branches from 6.5 down to 4.7, which together hold about 12 percent of the sites that report their version.
Table Of Content
- How the release unfolded
- Twelve items, 17 items, 22 vulnerabilities
- The unauthenticated item: a race in the update routine
- The other fixes: mostly Contributor-level stored XSS
- Backports: HelpHub says released, the servers say not yet
- The certificate update is bigger than its one line
- What to do now
- What is still unknown
- Related coverage and sources
Neither WordPress page gives severity scores or CVE identifiers, and none of the sources we read reports exploitation. What follows separates what WordPress’s pages and code establish from what rests on Patchstack’s analysis, and says where we checked a claim ourselves.
How the release unfolded
The timestamps below come from the repository comparison of the 7.1.3 and 7.1.4 tags, the Last-Modified headers on the download server, the WordPress News feed and Patchstack’s page, all on October 28 (UTC) unless stated.
| Time (UTC) | Event |
|---|---|
| 14:49 to 15:03 | Ten commits land on the 7.1 branch: eight security fixes, a Twenty Twenty theme bump and a pin of the bundled Gutenberg code |
| 15:56 and 16:11 | The “WordPress 7.1.4.” version commit, then the tag |
| 16:17 | The 7.1.4 zip appears on the download server |
| 16:19 to 16:32 | Zips for 7.0.8, 6.9.11, 6.8.12, 6.7.11 and 6.6.11 follow |
| 17:13 | The release post goes up on WordPress News |
| 18:34 | Patchstack publishes its write-up |
| 19:34 | No zip, releases-page entry or update offer exists for 6.5.14, 6.4.14 or any other older-branch fix |
Twelve items, 17 items, 22 vulnerabilities
The release post lists 12 vulnerability items plus a root-certificate update and names the reporters. The HelpHub page for the release lists 17 items and says WordPress 7.0 “is affected by all 22 vulnerabilities,” which is the source of the 22. Patchstack’s table has the same 17 rows. A keyword search of NVD for the release returned no records at 19:18 UTC.
Patchstack’s requirements column gives a useful sorting. By our count from that column, two of the 17 need no account: the update-window race, and an information disclosure that let an anonymous visitor see an unpublished Customizer changeset (HelpHub also describes the changeset item as reaching “unauthenticated visitors”). Ten need a Contributor account, two an Author account and one an Editor account. One needs a custom role that holds moderate_comments without edit access to the post, and one is a hardening fix that needs a username containing markup that something other than core has stored.
The unauthenticated item: a race in the update routine
The release post calls it “A weakness in the WordPress upgrade process which can lead to remote code execution during the upgrade window,” and HelpHub calls it “A race condition during core updates that could lead to remote code execution.” The reporter is Umut Bayram. Patchstack lists the requirement as “Nothing (Unauthenticated), but the attacker has to hit the seconds-long window while an update runs, and wp-content/upgrade/ must be reachable over the web.” It scored the attack complexity high and wrote that it “would not call it practical to exploit,” while noting that the bug “still needs no account and no interaction, the sink dates back to WordPress 2.8, and the window returns on every update, including unattended ones.”
WordPress unpacks each update package into a working folder under wp-content/upgrade/. The fix is in one commit, titled “Upgrade/Install: Improve the handling of the upgrade working directory”, and it touches two files:
| Change | File | What the 7.1.4 code does |
|---|---|---|
| Unpredictable folder name | class-wp-upgrader.php |
A new private method returns the package name, a hyphen and wp_generate_password( 16, false ), which is 16 characters drawn from letters and digits |
| Folder kept unlistable | class-wp-upgrader.php |
Cleanup now skips index.php, and a placeholder index.php is created if it is missing. A new comment says the directory is web-served and that the working folder’s name “cannot be discovered from a directory index” |
| No stray config copy | update-core.php |
wp-config.php joins wp-content and wp-includes/version.php in the list of paths update_core() does not copy, with the comment “Never copy a wp-config.php, which could have been written to the working directory.” |
The third change is not in the release post. We confirmed all three in the shipped files: the class-wp-upgrader.php in the 7.1.4 tag on GitHub has the same MD5 hash (9f2b60bdae6094c78b791ab7ccbffd3e) as the copy inside the 7.1.4 zip and as the value in WordPress.org’s checksum API, and the zips for 7.0.8, 6.9.11, 6.8.12, 6.7.11 and 6.6.11 contain the same three changes.
The source also shows that the old folder name was not guessable for every package. Downloaded packages pass through wp_tempnam(), which appends six random letters and digits to the file name, and the old unpacking code kept them. A zip uploaded through the admin keeps its own file name, so its folder name was predictable, which fits Patchstack’s wording that the name was “fully predictable” for “anything uploaded through the admin.” Our reading of the two fixes is that they close two routes to the name: predicting it from the package name, which the random suffix addresses, and reading it from a directory index, which the kept index.php addresses. Neither WordPress nor Patchstack says which update paths the reporter used, and the web server decides whether a listing is possible at all.
One consequence follows from how the updater is loaded. The update that installs 7.1.4 still unpacks its package with the 7.1.3 code, because the updater class is already in memory when it runs. That is our inference from the code, not a statement from WordPress, but it is why the web server rule below is worth adding before you update, not after.
The other fixes: mostly Contributor-level stored XSS
- Interactivity API. Patchstack counts seven of the 17 items as Interactivity API bugs with a common root: KSES, the filter that decides what HTML a user without
unfiltered_htmlcan save, allows anydata-*attribute with any value, and every Interactivity directive is adata-*attribute. The diff shows one fix titled “Limit bindings on object elements to global attributes” and a KSES change that drops adata-wp-bind--*directive on elements where KSES restricts attribute values, unless the bound attribute is one it allows with any value. - Block delimiter whitespace. The commit is titled “Editor: Align block-delimiter whitespace matching between the PHP and JavaScript parsers.” The PHP pattern now matches an explicit set of five characters (space, tab, form feed, carriage return and newline) where it used
\s. Patchstack says the two parsers disagreed about what counts as whitespace. - Customizer. A preview request with no changeset UUID could adopt the latest unpublished changeset. The code now requires the
customizecapability, and its comment says the UUID “serves as the secret key for previewing.” - Notes. For comments of type note, the REST controller now requires edit access to the note’s post in place of
moderate_comments. - Escaping and blocks. Two commits titled “Users: Escape user login” and “Privacy: Harden column_email() output escaping in request list tables” appear, by their titles and files, to correspond to the two items credited to Anthropic. Six block files (Categories, Comments Pagination Next and Previous, Image, Playlist and Post Navigation Link) also got small output-handling changes.
Anthropic is credited on two of the release post’s 12 vulnerability items. Counting the same way across the 7.1.1, 7.1.3 and 7.1.4 posts, Anthropic is credited on 7 of 30 items, and one 7.1.3 item is credited to Trail of Bits “in collaboration with OpenAI.” That counts credit lines, not how each bug was found, and we covered the first of those releases in WordPress 7.1.1 Patches an Unauthenticated Comment XSS as AI Firms Keep Finding Its Bugs.
Backports: HelpHub says released, the servers say not yet
For each branch from 7.0 down to 4.7, HelpHub gives the number of the 22 vulnerabilities that affect it and a fixed version, and for every one it says the version “has been released containing fixes.” The release post says only that the backports “are in progress and will ship as they become ready,” the same sentence the 7.1.1 and 7.1.3 posts used. Three WordPress.org surfaces agree with the release post: the zip server (including downloads.wordpress.org), the releases page and the version lists behind the update check.
| Branch | Affected, of 22 (HelpHub) | Fixed version named | Published at 19:34 UTC? | Share of reporting sites |
|---|---|---|---|---|
| 7.1 | the release itself | 7.1.4 | Yes, 16:17 | 64.3% |
| 7.0 | 22 | 7.0.8 | Yes, 16:19 | 7.2% |
| 6.9 | 22 | 6.9.11 | Yes, 16:23 | 6.6% |
| 6.8 | 20 | 6.8.12 | Yes, 16:25 | 5.1% |
| 6.7 | 20 | 6.7.11 | Yes, 16:27 | 2.6% |
| 6.6 | 19 | 6.6.11 | Yes, 16:32 | 1.3% |
| 6.5 and 6.4 | 17 | 6.5.14, 6.4.14 | No | 2.4% |
| 6.3 down to 5.9 | 9 | 6.3.14, 6.2.15, 6.1.16, 6.0.18, 5.9.20 | No | 3.7% |
| 5.8 down to 5.0 | 6 | 5.8.19 down to 5.0.31 | No | 4.3% |
| 4.9 | 4 | 4.9.35 | No | 1.0% |
| 4.8 and 4.7 | 2 | 4.8.34, 4.7.39 | No | 0.6% |
| 4.6 and earlier | no longer supported | none | Not applicable | about 1% |
The shares come from WordPress.org’s version statistics, which cover the sites that check in. The unshipped branches sum to about 12 percent, and the 4.6 and earlier row is about 1 percent. We also asked the update-check API what a site on 6.5.13 is offered: 7.1.4 and the five other new releases, and no 6.5.14. A 7.1.3 site is offered 7.1.4 both as an upgrade and as a background update.
That may only be timing. On October 6 the six newest branches shipped within 11 minutes of the 7.1.3 zip, the first of the 19 older branches (6.5.13) followed after 2 hours 8 minutes, and the last (4.7.38) after 3 hours 25 minutes. Today the first older branch had not appeared after 3 hours 17 minutes. Public data does not say whether that is a delay or a different schedule. Until the fixed versions exist, a statement that they are available, including Patchstack’s “Backports are already available: 7.0.8, 6.9.11, 6.8.12, 6.7.11, 6.6.11, 6.5.14, 6.4.14 and down to 4.7.39,” describes releases that, at that hour, existed in WordPress’s documentation but not on its servers.
The certificate update is bigger than its one line
The release post’s last item reads “An update to the bundled root certificates due to the eMudhra revocation.” Comparing the 7.1.3 and 7.1.4 copies of ca-bundle.crt shows a full refresh. The file moves from a Mozilla snapshot of July 16 to one of October 20, committed on October 26 from composer/ca-bundle 1.6.0, and goes from 119 certificates to 118.
- Removed (5):
emSign ECC Root CA - C3,emSign ECC Root CA - G3andemSign Root CA - C1, which are eMudhra roots, plusAtos TrustedRoot 2011andePKI Root Certification Authority. - Added (4):
SECOM TLS ECC Root CA 2024,SECOM TLS RSA Root CA 2024,Telia EC TLS Root CA v3andTelia RSA TLS Root CA v3. - Kept:
emSign Root CA - G1.
WordPress’s HTTP API validates outbound HTTPS requests against this file by default (the default sslcertificates path in class-wp-http.php), so a site that has not updated keeps trusting the removed roots. All six shipped zips carry the October 20 snapshot header and list only emSign Root CA - G1 among the emSign roots. Our earlier report on the eMudhra keys covers why those roots were pulled.
What to do now
- Add the web server rule first. Patchstack recommends denying access to
wp-content/upgrade/at the web server and checking that the folder is not listable. For nginx, the rule below passed our test on nginx 1.31.8 (Windows build) against a throwaway document root with directory listing switched on. Without the rule the folder listing and a file inside it were served. With it, the folder and a file inside returned 403, including with a percent-encoded letter, doubled slashes and a../detour in the path, an unrelated file still returned 200, and the path without its trailing slash got a 301 to the slashed form, which then returns 403. - Update. On 7.1 and the five branches with new releases, take the minor update from the Dashboard, or let background updates do it. Do not expect a fix on 6.5 or older yet. HelpHub names one, but it was not downloadable at 19:34 UTC, so the web server rule matters most there, and WordPress notes that “only the most recent version of WordPress is actively supported.”
- Check who holds Contributor and above. Patchstack points out that all but two of the 17 items start from a Contributor or higher account.
For nginx 1.31.8 (the location documentation says matching runs on a normalized URI, after decoding and removing relative path components), place this in the server block:
location ^~ /wp-content/upgrade/ {
return 403;
}
For Apache HTTP Server 2.4, the mod_alias documentation says a status outside 300 to 399 takes no URL argument and that RedirectMatch is equivalent to Redirect with regular expressions, so this line in the virtual host or an .htaccess file in the site root should do the same job. We did not run it. If WordPress lives in a subdirectory, add that directory to the path in either rule.
RedirectMatch 403 "^/wp-content/upgrade/"
To check a site, request the folder and look at the status and the first lines of the body. A 403 or 404 is what you want. A 200 whose body begins with “Index of” means directory listing is on.
curl -s -o /dev/null -w "%{http_code}\n" https://example.com/wp-content/upgrade/
curl -s https://example.com/wp-content/upgrade/ | head -n 5
With WP-CLI, the wp core update documentation says the command “Defaults to updating WordPress to the latest version” and describes --minor as performing only minor-release updates, which keeps a site on its branch. The wp core version and wp core check-update commands report the installed version and any available update. We took this syntax from the documentation and did not run it.
wp core version
wp core check-update
wp core update --minor
What is still unknown
- Severity and identifiers. The notice and HelpHub give neither scores nor CVE identifiers, and Patchstack describes only the race’s attack complexity. NVD had no matching records at 19:18 UTC.
- Exploitation. None of the three pages reports any. Nothing in CISA’s Known Exploited Vulnerabilities catalog (version 2026.10.28) refers to this release. The catalog holds three WordPress Core entries from this year, all from earlier fixes: CVE-2026-60137 and CVE-2026-63030, added on July 21, and CVE-2026-87902, added on September 25.
- Reach of the race. Which update paths were practical to attack, and on how many sites the folder was listable, is not stated.
- Backport timing. When the 19 older-branch releases ship, and whether their zips carry every fix that applies to those branches, is not yet visible.
Related coverage and sources
7.1.4 is the fourth WordPress core release with security fixes since September 17: 7.1.1 came out that day, 7.1.2 and its unauthenticated file-inclusion bug followed on September 22, and 7.1.3 on October 6. For the earlier KEV-listed core entries see our report on the 7.0.2 critical RCE chain. The PHP flaws we covered in our PHP2Shell report are separate: WordPress’s own PHP notice says “No WordPress update is required or planned for these issues.”
Sources: WordPress 7.1.4 release post; HelpHub, Version 7.1.4; Patchstack, WordPress 7.1.4 Security Release; wordpress-develop comparison of 7.1.3 and 7.1.4; WordPress 7.1.3 release post; WordPress 7.1.1 release post; update-check API; version status list; version statistics; WordPress.org releases page; composer/ca-bundle 1.6.0; CISA KEV catalog; WP-CLI documentation; nginx documentation; Apache documentation.








No Comment! Be the first one.