WordPress security this week: the update became the attack, and six plugins are being exploited
WordPress 7.1.4 fixes 22 security issues, and one of them is unlike the rest: for a few seconds during every full Core update since 4.7, a working copy of the WordPress installer sat in a web-reachable folder with a guessable name, and an attacker who requested it in time could run an installation against a database they control. Wordfence saw more than 18,500 requests for those staged installer paths in the first 21 hours after the release, and CISA added the flaw to its Known Exploited Vulnerabilities catalog on 3 November. Around it, six plugin flaws carry Patchstack’s exploited label, a Brotli decoder bug reaches WordPress through libcurl without WordPress shipping a byte of Brotli, cPanel closes a root-level file write and an unauthenticated calendar read, CloudLinux now has fixed kernels in production for last week’s local root, and PHP2Shell scanning ran to nine million rule matches in six days.
Prepared by G. Schad, WordPress and Linux security specialist
CVE-2026-119977: a race during full-package updates, 4.7 through 7.1.3, fixed in 7.1.4 and backports down to 4.7.39 on 28 October; 18,500+ probes in 21 hours per Wordfence; in CISA’s KEV from 3 November
Plugins
Exploited per Patchstack: Contact Form 7 6.2.4, Gravity Forms 3.1.3, WP Project Manager 4.1.2, FunnelKit Automations 3.8.6.2, Uncanny Toolkit for LearnDash 3.8.3, WP Social 3.2.3. Inventory also FormFlow 3.11.0, Web 2.0 Directory and Newsmatic 1.5.1
Brotli · CVE-2026-111497
In CISA’s KEV since 27 October; reachable from WordPress through pingbacks and other outbound requests because libcurl decompresses the reply; crash and CPU exhaustion demonstrated against PHP, no public PHP code-execution chain. Fix is the system library and rebuilt images
Hosting stack
cPanel & WHM: root file write (CVE-2026-105476), unauthenticated calendar and contact read (CVE-2026-105475), Roundcube 1.6.20 (CVE-2026-113386). CloudLinux: fixed kernels in production for 7h, 8, 9 and 10; ELS pending. PHP: CVE-2026-115560 still unfixed, keep session upload progress off
This week in one minute
The short version: what changed in the week to 2 November
If you read one section, read this one. The Core flaw is the priority because it is in CISA’s catalog and because the exposure is created by the thing you do to fix it: a full-package update extracts WordPress into wp-content/upgrade/, and until 7.1.4 the folder name was predictable and the installer inside it was reachable from the web for as long as the extraction took. Patchstack rates the attack as impractical because the window is seconds long; Wordfence, the CVE numbering authority for it, scores it 8.1 and logged more than 18,500 attempts in its first 21 hours; CISA added it on 3 November. All three can be true at once. The window is short, the attackers are polling for it anyway, and nobody has published a confirmed compromise. Update, and deny web access to the folder so the window closes for good, including on fleets with slow storage or staged rollouts where the extraction takes longer than a few seconds.
Six plugin flaws carry Patchstack’s known-to-be-exploited label this week, and three of them give an anonymous visitor an account or code execution: WP Project Manager’s remote code execution, and the authentication bypasses in Uncanny Toolkit for LearnDash and WP Social. Contact Form 7’s file upload needs the server to help, by listing directories or interpreting what lands in the upload folder; the two object injections, in Gravity Forms and FunnelKit Automations, need a gadget chain the site happens to carry. Below the application, Brotli is the item that updating WordPress cannot touch, cPanel has three fixes including one that turns any panel login into root, and CloudLinux’s kernels are finally out.
Figure 1 · The week at a glance
The update itself was the attack surface, and six plugin flaws are being exploited around it.
Component
Status on 2 November
What to do
WordPress Core ≤ 7.1.3 · CVE-2026-119977
Update-window RCE; 18,500+ probes; KEV 3 Nov
7.1.4 or branch backport; deny wp-content/upgrade/
Six plugins · CF7, Gravity Forms, Project Manager, FunnelKit, Uncanny, WP Social
The six items that need action in the week to 2 November 2026: the Core update window, six exploited plugins, a decoder library below PHP, the panel, the kernel and the PHP interpreter.
WordPress Core · exploited after release
CVE-2026-119977 affects 4.7 through 7.1.3 and is fixed in 7.1.4 with backports for every branch down to 4.7.39. 7.1.4 appends sixteen random characters to the extraction folder, keeps an index.php in it, and refuses to promote a wp-config.php out of the working directory. Deny the folder at the web server regardless, because a PHP-level firewall cannot see the request: the staged installer loads WordPress from its own files.
Plugins · six exploited, three to inventory
Contact Form 7 6.2 to 6.2.3 lets files that failed validation stay on disk; Gravity Forms and FunnelKit Automations deserialise visitor input; WP Project Manager runs a validation callback before its permission check; Uncanny Toolkit and WP Social log a visitor in as an existing user. FormFlow, Web 2.0 Directory and the Newsmatic theme have no exploited label yet and critical or high fixes.
Brotli · below the application
A pingback or any outbound fetch makes libcurl decompress an attacker’s Brotli reply before WordPress sees it. A crash and a worker pinned at full CPU have been reproduced against PHP; code-execution chains exist for Node.js and Bun, not PHP. The fix is the operating system’s brotli-libs or libbrotli1 and a rebuild of every container image that carries its own copy. EasyApache’s ea-brotli and Node.js updates are separate packages and do not patch the one libcurl loads.
cPanel, CloudLinux, PHP
cPanel 11.110.0.154, 11.134.0.67, 11.136.0.51 and 11.138.0.19 close a root-level file write by an authenticated user, an unauthenticated read of calendars and contacts, and ship Roundcube 1.6.20. CloudLinux 7h, 8, 9 and 10 have fixed kernels in production since 28 and 30 October; 8 ELS and 9 ELS are still pending and the only livepatch is for 10. PHP’s CVE-2026-115560 has no fix yet; Imunify counted about nine million PHP2Shell rule matches between 21 and 26 October.
WordPress Core · CVE-2026-119977
WordPress 7.1.4: the update process left the installer on the web for a few seconds
WordPress 7.1.4 was released on 28 October as a security release with 22 fixes, most of them stored cross-site scripting reachable by Contributor or higher accounts, plus an information disclosure of unpublished Customizer changes, a permissions bug in post notes, and an update to the bundled root certificates. The one that matters to this briefing was reported by Umut Bayram and described by WordPress as a race condition during core updates that could lead to remote code execution. It affects every version from 4.7 to 7.1.3, which is to say every WordPress that has updated itself in the last decade. Wordfence assigned CVE-2026-119977 and scored it 8.1; Patchstack’s database entry carries a 9 with a Low priority and the note that exploitation is impractical. CISA added it to the Known Exploited Vulnerabilities catalog on 3 November with a 6 November deadline for federal agencies, which is a three-day window and a signal of how it reads the evidence.
The mechanism, from Patchstack’s reading of the code, is this. When WordPress installs or updates itself from a full package, it extracts the archive into a working folder under wp-content/upgrade/, a directory the web server serves. Before 7.1.4, the folder name came from the package name, so for an administrator-uploaded or standard update it was predictable. The cleanup routine then deleted everything in wp-content/upgrade/, including the index.php that stops directory listing. The extracted copy is a complete WordPress, and it contains wp-admin/setup-config.php, the installer that runs without the site’s configuration. An attacker who requests that file while the extraction exists can run the installer against a database they control, and from there execute code. The window lasts as long as the extraction and copy take, which is seconds on fast storage and longer on NFS, saturated disks or staged deployments. It recurs on every update, including unattended ones, and it needs no account.
The paths the attackers request look like this, with the directory name varying by package:
7.1.4 adds three defences: sixteen random characters appended to the extraction folder name, an index.php that is recreated and no longer deleted, and wp-config.php added to the list of files never copied out of the working directory, a change Patchstack found in update-core.php and the release post does not mention. The backports shipped the same day for every branch WordPress still patches: 7.0.8, 6.9.11, 6.8.12, 6.7.11, 6.6.11, 6.5.14, 6.4.14 and so on down to 4.7.39. WordPress’s own documentation lists which of the 22 issues reach each branch; 7.0 and 6.9 get all 22, 6.8 and 6.7 get 20, 6.6 gets 19. The 28 October announcement said the backports were in progress and would ship as ready, so a site on an older branch should be checked rather than assumed. 4.6 and earlier get nothing.
Wordfence published a firewall rule at 20:30 UTC on 28 October and saw the first matching request nine minutes later. In the first 21 hours it counted more than 18,500 requests for staged setup-config.php paths. Those are attempts seen by one vendor’s firewall, not compromises; Wordfence has not reported a successful one, and neither has anyone else as of this briefing. Treat the number as proof that the path is being polled at scale, and your own logs as the only evidence about your own sites.
If a site updated between 28 October and the fix, read these before you call it clean
For every site that ran a Core update while wp-content/upgrade/ was web-reachable, which until this week was all of them. The order is preserve, then search, then verify, then audit. Nothing here changes the site.
01
Search the access logs for the staged installer
On cPanel the per-domain logs are in domlogs; elsewhere use the vhost access log. Any hit is worth a ticket, a 200 is an incident:
A 403 after this week’s deny rule is the rule working. A 404 from before it means the attacker missed the window. A 200 or 302 means the installer answered.
02
Look for what the extraction left behind
Between updates the folder holds only index.php. Anything else, and above all a wp-config.php or any PHP file that is not index.php, is evidence:
Check the live wp-config.php against a known-good copy as well, since the pre-7.1.4 copy routine could promote one.
03
Verify the Core files
Confirm the version and that the Core files match the release checksums, with plugins and themes skipped so nothing loaded can interfere:
WP-CLI
$ wp core version --skip-plugins--skip-themes$ wp core verify-checksums --skip-plugins--skip-themes
A checksum failure on a file the release touched is expected after a partial update; a failure on a file it did not touch, or an extra file, is not.
04
Audit who and what arrived after the update
Administrators, application passwords, plugins, must-use plugins and cron events created in the hours after an update are the shapes a successful run would take:
shell
$ wp user list --role=administrator--fields=ID,user_login,user_email,user_registered--skip-plugins--skip-themes$ wp user application-password list "$(wp user list --role=administrator --field=ID --skip-plugins --skip-themes | head -1)"--skip-plugins--skip-themes$ wp plugin list --fields=name,status,version,update--skip-plugins--skip-themes$ wp cron event list --fields=hook,next_run_relative,recurrence--skip-plugins--skip-themes$ ls-la--time-style=long-iso wp-content/mu-plugins wp-content/plugins |sort-k6,7
Then the process table and outbound connections for the account during the same window, which on shared hosting is where the question becomes a server question.
Six plugin flaws under exploitation, from a 10-million-install form to a 5,000-install project board
Patchstack marks all six as known to be exploited. The fixed version is the one to install; the current version on WordPress.org is given where it has moved on. Three are usable by anyone against a stock install; the other three need something from the server or the site.
Contact Form 7 is the one most people will find on their servers, and the one whose severity most depends on the server. The vendor’s 29 October notice says the target is any form with a file field on a server that lists directory contents; Patchstack adds that the upload folder name is random and not disclosed, so an attacker who cannot list the directory has to guess. Two server settings decide the outcome: whether Options -Indexes, or the nginx equivalent, is in force for the uploads tree, and whether PHP executes there at all. A site that already forbids PHP in wp-content/uploads and does not list directories has turned this from a takeover into a storage nuisance. Update to 6.2.4 anyway, then look in the wpcf7_uploads folder and the rest of uploads for anything with a PHP, phar, pht or phps extension, a double extension, or a .htaccess that was not there before.
The three that need nothing from the server are the ones to treat as incidents on any site that was exposed. WP Project Manager’s flaw is plain remote code execution reachable from the internet, and its 4.1.2 changelog describes it only as a fix to how project changes are checked before saving. Uncanny Toolkit and WP Social both let a visitor become an existing user, which on a LearnDash or membership site means the administrator who set it up. For those three, review administrators, role changes, password resets and sessions since the fix dates, and look for PHP in uploads, mu-plugins and cron on the Project Manager sites. Gravity Forms and FunnelKit are object injections: no gadget chain, no code execution, but Patchstack marks both exploited, which means someone is sending the payloads and finding chains somewhere. Gravity Forms is a premium plugin that does not auto-update by default and whose fix shipped on 1 October under a one-line changelog, so a site that watches only for security releases has been exposed for a month.
Plugin and CVE
Vulnerable
Fix
What an attacker gets
Contact Form 7 — no CVE yet, CVSS 8.1
6.2 to 6.2.3
6.2.4 (current: 6.2.4.1)
Unauthenticated file upload through the feedback REST route. 6.2 removed the file-type check that ran before storage, so files land in the wpcf7_uploads folder before validation and rejected files stay; the remaining blocklist misses phar, pht, phps and .htaccess. The folder name is random, which is why Patchstack rates complexity high and priority medium. 10 million installs
Gravity Forms — CVE-2026-103039, CVSS 9.8
≤ 3.1.2
3.1.3 (current: 3.2.1)
Unauthenticated PHP object injection through a List-type Post Custom Field; code execution if the site carries a gadget chain. A proof of concept is public. Fixed on 1 October with a changelog line reading only “security enhancements”, four weeks before disclosure
WP Project Manager — CVE-2026-116512, CVSS 9.8
≤ 4.1.1
4.1.2
Unauthenticated remote code execution: a REST route’s validation callback runs before its permission check, so the plugin’s capability gate is never reached. A public exploit exists. 5,000 installs
FunnelKit Automations — CVE-2026-39738, CVSS 9.8
≤ 3.8.6.1
3.8.6.2 (current: 3.9.0)
Unauthenticated PHP object injection; code execution depends on a gadget chain. The 3.8.6.2 changelog says “hardened data validation across abandoned cart capture and contact fields” and never uses the word security. 20,000 installs
Uncanny Toolkit for LearnDash — CVE-2026-119096, CVSS 9.8
≤ 3.8.2
3.8.3
Unauthenticated authentication bypass through the email parameter of the front-end login action: log in as an existing user without the password. The changelog also records a two-factor integration that completed a login without applying the second factor. 20,000 installs
WP Social (Wp Social Login and Register Social Counter) — CVE-2026-103898, CVSS 8.1
≤ 3.2.2
3.2.3
Unauthenticated authentication bypass: the social-login REST callback’s permission check always passes and the account is matched by the email string the OAuth provider returns. Fixed on 14 October, published as exploited on 30 October. 70,000 installs
Three more to inventory this week: FormFlow, Web 2.0 Directory and the Newsmatic theme
No exploited label on any of these as of 2 November. Two are SQL injections and one is an unauthenticated upload, which is the kind that gets a label within days.
Web 2.0 Directory is the awkward one: it is not on WordPress.org, its CVE record names no fixed version, and the secondary reports disagree between 2.10.13 and 3.0.0. Check the vendor’s changelog on CodeCanyon for the entry that mentions the level filter, and treat anything at 2.10.12 or below as vulnerable until then. FormFlow is the one to move first, because an unauthenticated upload with a public nonce is the pattern that goes from published to exploited fastest.
Component and CVE
Vulnerable
Fix
What an attacker gets
FormFlow, listed on WordPress.org as SimpleForm — CVE-2026-118235, CVSS 9.8
≤ 3.10.2
3.11.0
Unauthenticated file upload: a trailing dot on the file name bypasses the extension and MIME checks in the upload handler, and the only token needed is a nonce printed into every public form
Web 2.0 Directory, sold on CodeCanyon — CVE-2026-15272, CVSS 6.5
≤ 2.10.12
Later than 2.10.12; the vendor changelog gives 3.0.0
Time-based SQL injection through the level filter parameter, which is used unquoted in an integer context so WordPress’s slash escaping does nothing. The CVE record calls it unauthenticated and scores it with low privileges required; read the record before deciding which
Brotli: WordPress does not ship it, and a pingback still reaches it
CVE-2026-111497 is an out-of-bounds write in the Brotli decoder, affecting 1.0.3 through 1.2.0 and fixed on 21 October in 1.0.10, 1.1.1 and 1.2.1. CISA added it to the Known Exploited Vulnerabilities catalog on 27 October with a 10 November deadline. It is a library bug, not a WordPress one, and that is exactly why it belongs here: the fix is a package on the server, and nothing in the WordPress update stream will ever deliver it.
Patchstack’s 30 October analysis traces the route. An unauthenticated pingback.ping call to xmlrpc.php makes WordPress fetch the attacker’s source URL with wp_safe_remote_get(). WordPress’s cURL transport sets CURLOPT_ENCODING to an empty string on every request, which asks libcurl to accept and decompress any encoding the server offers; a reply with Content-Encoding: br is therefore decompressed by the system’s Brotli library inside curl_exec(), before PHP or WordPress sees a byte of the body. The same decoder is reached by oEmbed fetches, feed fetches through SimplePie, and any plugin that fetches a visitor-supplied URL. PHP’s own note on its 26 October Windows rebuilds says the vulnerable decoder is reachable through the cURL extension only when automatic decompression is enabled, which is off by default; WordPress turns it on.
What has been demonstrated against PHP is denial of service. A lab published on 27 October showed a worker killed outright and, with a payload under 100 bytes, a worker pinned at full CPU. No public, reproducible code-execution chain exists against PHP behind Apache or PHP-FPM; the chains that do exist target stock Node.js and Bun binaries, and one GitHub repository claims execution against a single pinned Docker image of WordPress, which this briefing could not verify. Say DoS, and plan for the chain to arrive.
On Debian and Ubuntu, the package is libbrotli1 and the distribution backports the fix into 1.1.0, so compare the package revision rather than the version: Patchstack’s example is 1.1.0-2+b7 vulnerable and 1.1.0-2+deb13u1 patched on Debian 13, with the suffix varying by release. The third command above lists processes still holding the old library after the update; restart them, which on a web server means Apache or nginx, PHP-FPM, and anything else that links libcurl.
cPanel: an authenticated user could write files as root, and anyone could read calendars
cPanel published two advisories dated 20 October whose CVE records became public on 2 November. CVE-2026-105476 is an improper link resolution flaw, CWE-59, that lets a remote authenticated user write arbitrary root-owned files, which is privilege escalation to root by another name; it is scored 8.8 with a vector that needs only low privileges, and it is credited to a researcher known as Boomerang. The briefing source this issue draws on describes the starting point as a reseller account; the CVE record says authenticated users without qualification. Until cPanel’s text has been read against your own account types, assume any login to the panel is in scope. CVE-2026-105475 is a NUL-byte handling flaw that lets an unauthenticated remote attacker read any mail account’s calendar and contact data, scored 8.7 on CVSS 4.0. Both are fixed in 11.110.0.154, 11.134.0.67, 11.136.0.51 and 11.138.0.19; the 138 change log dates 138.0.19 to 26 October and lists only a security-hardening line for them.
The same 138.0.19 build updates Roundcube to 1.6.20, which Roundcube released on 19 October alongside 1.7.5 with 20 security fixes. The one with the highest reach is CVE-2026-113386, an IMAP command injection: a logged-in webmail user can put a carriage return and line feed into the uid parameter of the headers and view-source actions and have the IMAP server run a command of their choosing on their own mailbox. A sibling, CVE-2026-114720, does the same through the flag parameter of the mark action. Authenticated, scored 7.1, and in a shared-hosting context the authenticated user is any customer or any phished mailbox. Check the Roundcube version a server actually runs rather than the cPanel branch, and on branches other than 138 read the change log for the build that carries 1.6.20.
A phpMyAdmin WebAuthn flaw disclosed this period is reported, in the briefing source, as not affecting the phpMyAdmin that cPanel bundles, on cPanel’s own assessment. This briefing could not find a published cPanel statement to quote, so treat that as unconfirmed, and in any case it says nothing about a phpMyAdmin installed by hand outside the managed package.
Vulnerability
Who can use it
What it gives
Fixed in
CVE-2026-105476, CVSS 8.8
An authenticated cPanel or WHM user; the CVE vector needs low privileges
Arbitrary file write as root, so full control of the server
CloudLinux: the fixed kernels are out for 7h, 8, 9 and 10, and they need a reboot
Last week’s briefing covered ZDI-CAN-33367 when it had a public exploit, no fixed kernel on any line, and a livepatch only for CloudLinux 10. CloudLinux’s advisory has been updated since. Fixed kernels moved to production on 28 October for CloudLinux 9 and 10, through the AlmaLinux kernel updates, and on 30 October for CloudLinux 7 Hybrid and CloudLinux 8. The ELS variants of 8 and 9 were still pending on their extended-support channel at the cut-off, with 8 ELS waiting on a kernel uplift to 5.14 and no livepatch possible; CloudLinux for Ubuntu 22.04 waits on Canonical. KernelCare has moved less: the livepatch is in production for CloudLinux 10 only, in review for 9, in progress for 8 and in preparation for 7 Hybrid and 9 ELS. Still no CVE.
Installing the package is not the fix; running it is. A kernel that is installed and not booted protects nothing, so the sequence is update, reboot, and compare the running version against the table:
shell
$ dnf update "kernel*"$ reboot$ uname-r
Use yum on CloudLinux 7 Hybrid. Where a reboot cannot happen today, keep the mitigation from last week in place, which newer CloudLinux 8 and 9 installs and every CloudLinux 10 already have by default, and schedule a short window:
PHP · PHP2Shell, CVE-2026-115560 and the Updraft leftovers
PHP2Shell two weeks on: nine million rule matches, and a second advisory still without a fix
Imunify360 published its fleet numbers for the week after PHP2Shell: close to 3 million attack requests against roughly 100,000 servers and 1.7 million sites, a peak on 24 October of 1.3 million attempts in a day with 99.0 percent blocked, and about 9 million matches on the dedicated PHP2Shell rules between 21 and 26 October, of which about 6.25 million were from blocking rules and the rest from logging ones. No sign of a successful compromise on the fleet, by its account. Two caveats from its own write-up: the blocking rules cover the upload-progress path, which is CVE-2026-109619, while the out-of-memory path of CVE-2026-109618 has logging rules only; and the rules are a virtual patch that stops known request shapes at the edge while the vulnerable interpreter stays as it is. Nine million matches in six days is the argument for checking what is actually running rather than what the repository says.
The things that stay unpatched after a fleet update are the ones outside the update path: a PHP built from source years ago for one application, an alt-php or ea-php branch no domain officially selects but a .htaccess handler still points at, a CageFS skeleton that was not refreshed, a PHP-FPM pool that was never restarted after the packages changed, and a ModSecurity or Imunify rule that was disabled for one domain during an incident and never re-enabled. Each is a one-line check:
shell
$ /usr/local/cpanel/bin/rebuild_phpconf--current$ for p in /opt/cpanel/ea-php*/root/usr/bin/php /opt/alt/php*/usr/bin/php;doecho"$p $($p -r "echo PHP_VERSION;")";done$ rpm-q--changelog ea-php81-php-cli |grep-m1-E"CVE-2026-(109618|109619)"$ grep-rl"ea-php\|alt-php" /home/*/public_html/.htaccess 2>/dev/null|head$ imunify360-agent config show |grep-iA3"MOD_SEC"
PHP’s informational advisory of 23 October for CVE-2026-115560, the second session-upload-progress issue, still has no fixed release as of 2 November; PHP’s archive shows only the 26 October Windows rebuilds for Brotli since. The mitigation stands: session.upload_progress.enabled set to 0, on every SAPI and every branch, with the workers restarted. Because php.ini, a .user.ini, a PHP-FPM pool file and a per-domain MultiPHP setting can each override the others, read the effective value from the interpreter rather than the file:
shell
$ for p in /opt/cpanel/ea-php*/root/usr/bin/php /opt/alt/php*/usr/bin/php;doecho"$p $($p -r "echo ini_get('session.upload_progress.enabled');")";done$ grep-rs"upload_progress" /home/*/public_html/.user.ini /opt/cpanel/ea-php*/root/etc/php-fpm.d/*.conf
What this week means: the update is attack surface, and the site is a step toward the server
The Core flaw changes the threat model for the one operation every site performs on a schedule. Updating is supposed to be the safe moment, and for ten years it was also the moment a complete, unconfigured WordPress was reachable on a guessable path. The fix in 7.1.4 is good, and it is still a fix inside the window; the control that removes the window is a web-server rule denying wp-content/upgrade/ from the internet, applied everywhere and left in place. Fleets with staggered rollouts, slow I/O, network storage or long deployment pipelines should assume their window was longer than the seconds Patchstack measured, and should read their logs for the week accordingly.
On a shared host the six plugin flaws, the panel flaw and the kernel are one chain. A form upload or a REST route gives an attacker a shell as one customer. The shell reads wp-config.php, cookies, API keys and whatever credentials the account kept; a reused password or a token reaches cPanel, mail or a reseller login; CVE-2026-105476 takes that login to root on an unpatched build, or ZDI-CAN-33367 takes the shell to root on an unbooted kernel; and from root every site, mailbox and database on the node is the attacker’s. The first-day investigation of a single compromised site therefore has to include the panel’s access logs, the mail logs, authentication records, the process table and recent changes under /etc and /root, not only the public_html that raised the alarm.
Brotli is the reminder that outbound requests are an input. A pingback, a server-side request forgery, an oEmbed, a feed or a webhook all fetch what an attacker chooses, and the reply is processed by native libraries before the application sees it. An inventory of the destinations PHP is allowed to reach, an egress proxy or firewall for the web user, and logging of outbound DNS and HTTP are defences against this week’s decoder bug and against the command-and-control traffic that follows any of the other items.
Then update every site to 7.1.4 or the backport for its branch and confirm the version afterwards on every node and replica, since the announcement said backports would ship as ready:
02
Verify Core and look back
Run the four steps in the Core indicators section above: access logs for setup-config.php and install.php under wp-content/upgrade/, leftovers in the folder, checksums, and the administrators, application passwords, plugins and cron created after each update since 28 October.
03
Find and fix the six exploited plugins
Across every site on the server, list the six and update or remove them:
shell
$ for s in /home/*/public_html;dowp plugin list --path="$s"--skip-plugins--skip-themes--fields=name,version--format=csv2>/dev/null|grep-E"^(contact-form-7|gravityforms|wedevs-project-manager|wp-marketing-automations|uncanny-learndash-toolkit|wp-social),"|sed"s|^|$s |";done
Targets: Contact Form 7 6.2.4, Gravity Forms 3.1.3, WP Project Manager 4.1.2, FunnelKit Automations 3.8.6.2, Uncanny Toolkit for LearnDash 3.8.3, WP Social 3.2.3, or the current release. Gravity Forms is premium and updates only with a valid licence; where it cannot be updated today, deactivate it.
04
Review the exposure window for each
Contact Form 7: list the upload folders for PHP, phar, pht, phps, double extensions and .htaccess files, and confirm PHP does not execute in uploads. Uncanny Toolkit and WP Social: administrators, role changes, password resets and sessions since mid-October. WP Project Manager: treat as code executed; PHP in uploads and mu-plugins, cron, the account’s crontab and processes. Gravity Forms and FunnelKit: the same as Project Manager if any gadget-bearing plugin is installed.
shell
$ find /home/*/public_html/wp-content/uploads -type f \( -iname"*.php*"-o-iname"*.phar"-o-iname"*.pht"-o-iname"*.phps"-o-name".htaccess" \) -newermt"2026-10-01"-ls
05
Update cPanel & WHM and review privileged state
Check the build and force the update if it is below the fixed one for its branch:
Then review reseller accounts, API tokens, SSH authorized_keys for root and resellers, changes under /root and /etc since 20 October, scripts in /usr/local/cpanel/hooks and the standardized hooks list, and root’s crontab.
06
Patch Brotli where libcurl loads it
On RPM systems update brotli and brotli-libs; on Debian and Ubuntu, libbrotli1 by package revision. Restart every process still holding the old library, rebuild container images from a patched base, and remember that ea-brotli and ea-nodejs22 are different packages:
Until then, block xmlrpc.php at the web server and install Patchstack’s must-use plugin that sets the cURL encoding to identity.
07
Boot the fixed CloudLinux kernel
Update, reboot in a short window, and confirm the running kernel is at or above the table above:
shell
$ dnf update "kernel*"$ uname-r
On 8 ELS, 9 ELS and Ubuntu, and anywhere the reboot has to wait, keep user.max_user_namespaces at 0 and on CloudLinux 10 confirm the KernelCare patch with kcarectl --patch-info.
The next 48 hours, and the hardening that keeps this week from repeating
24 to 48 hours · the inventory items
FormFlow to 3.11.0, Newsmatic to 1.5.1, Web 2.0 Directory to the vendor’s fixed release or removed. Confirm the ea-php and alt-php branch each domain actually runs, that every branch carries the PHP2Shell backport in its package changelog, and that PHP-FPM pools and the web server were restarted after the packages and Brotli changed. Keep session.upload_progress.enabled at 0 until PHP ships the CVE-2026-115560 fix.
24 to 48 hours · the exceptions
List every ModSecurity and Imunify rule disabled per domain and every WAF exception made during an incident, and re-enable the ones that outlived their reason. Re-inspect accounts that had Updraft-related detections and remove the residual administrators, cron, mu-plugins and rewritten .htaccess files. Confirm that backups and snapshots taken since 17 October do not carry the same persistence as the live system.
This week · deny what should never be requested
Keep wp-content/upgrade/ denied at the web server everywhere. Forbid PHP execution in uploads and cache folders unless an application needs it, and forbid directory listing for the whole document root, which removes Contact Form 7’s precondition and most upload-flaw follow-ups. Block xmlrpc.php where nothing uses it.
This week · separate and limit credentials
Different passwords for WordPress, SFTP, cPanel, reseller and root, with multi-factor on the panel and every privileged account; WHM reachable only from a VPN or an allow-list where that is possible. The plugin-to-root chain above runs on reused credentials.
This week · control what leaves
Egress filtering for the PHP and web users, with outbound DNS and HTTP logged. It limits the Brotli route, server-side request forgery, and the command-and-control that follows a webshell.
This week · alert on the shapes of persistence
Alerts for a new administrator, a new mu-plugin, a persistent cron event, and any change to wp-config.php, .user.ini or .htaccess. Define which PHP and WordPress branches are supported, retire the rest explicitly, test a clean restore, and keep logs off the server that could be compromised.
Checklist
Thirty minutes per server: the ten checks that close this week
01
WordPress 7.1.4 or the branch backport on every site
Confirm from WP-CLI with plugins skipped, on every node, including staging and replicas that update on their own schedule.
02
No successful request to a staged installer
Search every access log for setup-config.php and install.php under wp-content/upgrade/ and note the status codes.
03
The six exploited plugins inventoried and fixed
Contact Form 7, Gravity Forms, WP Project Manager, FunnelKit Automations, Uncanny Toolkit for LearnDash, WP Social: updated, or deactivated and removed.
04
cPanel & WHM at or above the fixed build for its branch
11.110.0.154, 11.134.0.67, 11.136.0.51 or 11.138.0.19, with Roundcube 1.6.20.
05
Brotli patched on the host, in containers and in chroots
brotli-libs or libbrotli1 by package revision, old copies out of memory, images rebuilt.
06
The fixed CloudLinux kernel running
uname -r at or above the table; the namespace sysctl still at 0 where it cannot be.
07
PHP2Shell backports present on every active branch
The CVE identifiers in the package changelog of each ea-php and alt-php branch any domain uses, and the workers restarted.
08
session.upload_progress.enabled at 0 on every SAPI
Read from the interpreter, not the file, for every branch.
09
Recent administrators, cron, mu-plugins, SSH keys and API tokens reviewed
Since 20 October for the panel, since 28 October for the sites, since 17 October for anything UpdraftCentral touched.
10
Logs preserved and a ticket opened for every match
Anything above that matched gets a case, with the logs copied off the server before cleanup starts.
Sources
Where every claim in this briefing comes from
This briefing was compiled on 2 November 2026 and revised on 4 November to add CISA’s 3 November catalog entry for CVE-2026-119977. Versions, dates and figures are quoted as the source reported them and were not independently re-measured. The Core mechanism and code changes are from Patchstack’s analysis; the branch list from WordPress’s own version documentation; the Wordfence request counts and rule timing from Wordfence’s post as reported, since its pages could not be read directly at compile time. Exploitation status for plugins is Patchstack’s known-to-be-exploited label; fixed versions were checked against the plugins’ WordPress.org changelogs and, for Gravity Forms, the vendor change log. The Brotli chain is Patchstack’s; PHP’s note on when the cURL extension reaches the decoder is from its 26 October announcement. cPanel’s two advisories returned an access error to this compiler, so their contents are taken from the CVE records they are cited in, and the reseller detail in the briefing source is flagged as such in the text. The cPanel phpMyAdmin assessment could not be sourced and is marked unconfirmed. CloudLinux’s kernel status is from its advisory as updated on 30 October; Imunify360’s figures are from its own fleet report. Where sources disagree, as they do on the Core flaw’s severity and on Web 2.0 Directory’s fixed version, both readings are given.
Common questions about this week’s WordPress security news
My sites auto-update. Was I exposed to CVE-2026-119977 anyway?
Yes, during every full-package update they ever ran, and during the one that installed 7.1.4. The flaw is in the update process itself, so the exposure was the few seconds the extracted package sat in wp-content/upgrade/ with a predictable name. The attackers were polling for it from 28 October. Search the access logs for setup-config.php or install.php under that folder; a 200 is an incident, a 404 is a miss, and nothing at all is the usual result. Then deny the folder at the web server so the next update has no window.
Patchstack says the Core flaw is impractical and CISA says it is exploited. Which is right?
Both describe the same facts. The window is seconds long and the attacker has to guess the path within it, which is why Patchstack rates it low priority. Wordfence counted more than 18,500 attempts in 21 hours, which is why CISA lists it as exploited: the polling is real and cheap to run. Nobody has published a confirmed compromise. Update, deny the folder, read your logs, and do not spend the week arguing about the score.
Which of the six exploited plugins matter if I only have Contact Form 7?
Contact Form 7 matters on 10 million sites, and its severity depends on your server. Update to 6.2.4 or later. Then confirm that directory listing is off for the uploads tree and that PHP does not execute there; with both in place the flaw leaves junk files rather than a webshell. Look in wp-content/uploads for files with PHP-family extensions, double extensions or a new .htaccess, created since early October.
Does updating WordPress fix the Brotli flaw?
No. WordPress does not ship Brotli; it asks libcurl to decompress whatever a remote server sends, and libcurl uses the operating system’s Brotli library. The fix is the brotli-libs or libbrotli1 package, a restart of every process that had it loaded, and a rebuild of container images. Blocking xmlrpc.php removes the pingback route only; Patchstack’s must-use plugin that sets the cURL encoding to identity covers the rest until the package is in.
Who can use the cPanel root file-write flaw?
An authenticated user. The CVE record’s vector requires only low privileges; the briefing source this issue draws on describes a reseller account; cPanel’s advisory could not be read directly at compile time. Treat any panel login as in scope, update to 11.110.0.154, 11.134.0.67, 11.136.0.51 or 11.138.0.19, and review reseller accounts, tokens, SSH keys and recent root-level changes afterwards.
The CloudLinux kernel package is installed. Am I done?
Not until it is running. Reboot and confirm that uname -r prints a version at or above the one in the table for your line. On CloudLinux 8 ELS, 9 ELS and Ubuntu there is no fixed kernel yet, and the only protection is user.max_user_namespaces set to 0, which CloudLinux 10 and newer 8 and 9 installs already have by default. CageFS does not stop this exploit.
Is the PHP2Shell patching finished?
On servers where the packages were updated, the workers restarted, and the package changelog on every branch any site uses shows the two CVE identifiers, yes for CVE-2026-109618 and CVE-2026-109619. The separate CVE-2026-115560 still has no fixed release, so session.upload_progress.enabled stays at 0 on every SAPI. Imunify’s nine million rule matches in six days are the reason to check interpreters installed outside the package manager, CageFS skeletons and per-domain handlers rather than trusting the repository state.
Choose the response path
The containment plan should match the size of the incident.
The server under the sites
Get the upgrade folder, the panel, Brotli and the kernel checked and proven on every host.
Best when several servers need the Core update window reviewed in the logs, the cPanel builds and privileged state audited, the Brotli library verified in memory and in images, and the CloudLinux kernel confirmed booted, with a written result per host.
Get the finding classified and the site restored to a trusted state.
Best when a staged installer answered a request during an update, a form upload folder holds a PHP file, an exploited plugin left an administrator behind, or a cleaned site has come back, and you want every layer removed in one pass rather than one at a time.