Weekly briefing · 2 November 2026

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.

WordPress Core
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.

ComponentStatus on 2 NovemberWhat to do
WordPress Core ≤ 7.1.3 · CVE-2026-119977Update-window RCE; 18,500+ probes; KEV 3 Nov7.1.4 or branch backport; deny wp-content/upgrade/
Six plugins · CF7, Gravity Forms, Project Manager, FunnelKit, Uncanny, WP SocialExploited: upload, deserialisation, RCE, login bypass6.2.4 · 3.1.3 · 4.1.2 · 3.8.6.2 · 3.8.3 · 3.2.3; review uploads and admins
Brotli · CVE-2026-111497KEV 27 Oct; DoS via pingback; no PHP RCE chainOS brotli-libs; restart; rebuild images
cPanel & WHM · RoundcubeRoot file write · calendar read · Roundcube11.110.0.154 · 11.134.0.67 · 11.136.0.51 · 11.138.0.19
CloudLinux kernel · ZDI-CAN-33367Fixed kernels out for 7h, 8, 9, 10; ELS pendingInstall, reboot, confirm uname -r
PHP2Shell · CVE-2026-1155609M rule matches 21–26 Oct; 115560 still unfixedVerify backports; upload_progress off
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:

shell
/wp-content/upgrade/wordpress-7.1.4/wp-admin/setup-config.php
/wp-content/upgrade/wordpress-7.1.4/wp-admin/install.php

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.

BranchFixed versionOf the 22 issues
7.17.1.4All 22
7.07.0.8All 22
6.96.9.11All 22
6.86.8.1220
6.76.7.1120
6.66.6.1119
6.5 and 6.46.5.14 · 6.4.1417
6.3 down to 5.96.3.14 · 6.2.15 · 6.1.16 · 6.0.18 · 5.9.209
5.8 down to 5.05.8.19 · 5.7.21 · 5.6.23 · 5.5.24 · 5.4.25 · 5.3.27 · 5.2.30 · 5.1.28 · 5.0.316
4.9, 4.8, 4.74.9.35 · 4.8.34 · 4.7.394 · 2 · 2
4.6 and earlierNoneUnsupported; migrate

WordPress Core · what to look for

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.

  1. 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:

    shell
    grep -rhE "wp-content/upgrade/[^ ]+/(wp-admin/)?(setup-config|install)\.php" /usr/local/apache/domlogs/ | sort | uniq -c | sort -rn | head
    grep -rhE "wp-content/upgrade/" /var/log/nginx/*access* | grep -vE " (403|404) " | head

    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.

  2. 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:

    shell
    find /home/*/public_html/wp-content/upgrade -mindepth 1 -not -name index.php -ls
    find /home/*/public_html/wp-content/upgrade -name "wp-config.php" -o -name "*.php" -newer /home/*/public_html/wp-settings.php

    Check the live wp-config.php against a known-good copy as well, since the pre-7.1.4 copy routine could promote one.

  3. 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.

  4. 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.

Plugins · exploited

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 CVEVulnerableFixWhat an attacker gets
Contact Form 7 — no CVE yet, CVSS 8.16.2 to 6.2.36.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.23.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.14.1.2Unauthenticated 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.13.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.23.8.3Unauthenticated 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.23.2.3Unauthenticated 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

Plugins and themes · not yet exploited

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 CVEVulnerableFixWhat an attacker gets
FormFlow, listed on WordPress.org as SimpleForm — CVE-2026-118235, CVSS 9.8≤ 3.10.23.11.0Unauthenticated 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.12Later than 2.10.12; the vendor changelog gives 3.0.0Time-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
Newsmatic theme — CVE-2026-110184, CVSS 7.5 (Patchstack: 9.3)≤ 1.5.01.5.1Unauthenticated blind SQL injection through the slug parameter in the theme’s functions.php. 1.5.1 removes the parameter from the query

Brotli · CVE-2026-111497

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.

The checks and the fix, on RPM systems first:

shell
rpm -q brotli brotli-libs
dnf update brotli brotli-libs
grep -l "libbrotli.*(deleted)" /proc/*/maps 2>/dev/null | cut -d/ -f3 | sort -u

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.

shell
dpkg -l libbrotli1 | tail -1
apt-get install --only-upgrade libbrotli1

cPanel & WHM · three fixes

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.

shell
/usr/local/cpanel/cpanel -V
grep -m1 "RCMAIL_VERSION" /usr/local/cpanel/base/3rdparty/roundcube/program/include/iniset.php
/scripts/upcp --force

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.

VulnerabilityWho can use itWhat it givesFixed in
CVE-2026-105476, CVSS 8.8An authenticated cPanel or WHM user; the CVE vector needs low privilegesArbitrary file write as root, so full control of the server11.110.0.154 · 11.134.0.67 · 11.136.0.51 · 11.138.0.19
CVE-2026-105475, CVSS 8.7 (v4)Nobody needs to log inRead any mail account’s calendar and contact dataSame builds
CVE-2026-113386 (Roundcube), CVSS 7.1A logged-in webmail userRun arbitrary IMAP commands against the mailbox: read, delete, alterRoundcube 1.6.20 and 1.7.5; cPanel 138.0.19 ships 1.6.20

CloudLinux · ZDI-CAN-33367

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:

shell
sysctl user.max_user_namespaces
echo "user.max_user_namespaces = 0" > /etc/sysctl.d/99-zdi-33367.conf && sysctl --system
CloudLinux lineFixed kernelStatus at 2 November
CloudLinux 7Not affectedNothing needed
CloudLinux 7 Hybrid4.18.0-553.177.1.lve.1.el7hProduction since 30 October; livepatch in preparation
CloudLinux 84.18.0-553.177.1.lve.1.el8Production since 30 October; livepatch in progress
CloudLinux 8 ELSPending (5.14 uplift)No fixed kernel; no livepatch possible; mitigation only
CloudLinux 95.14.0-687.60.1.el9_8 or laterProduction since 28 October; livepatch in review
CloudLinux 9 ELSPendingNo fixed kernel; livepatch in preparation; mitigation only
CloudLinux 106.12.0-211.69.1.el10_2 or laterProduction since 28 October; livepatch in the production feed
CloudLinux for Ubuntu 22.04Via CanonicalPending; livepatch not started

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; do echo "$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; do echo "$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

Practical impact

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.

Actions · priority 0

Today: the Core update, the six plugins, cPanel, Brotli and the kernel

In this order. Work from a trusted device, preserve logs before changing a server under suspicion, and record what you change.

  1. 01

    Deny the upgrade folder, then update Core

    Add the web-server rule first so the window is closed while the update runs. Apache, in the vhost or a .htaccess inside the folder, and nginx:

    shell
    printf "Require all denied\n" > /home/USER/public_html/wp-content/upgrade/.htaccess
    location ^~ /wp-content/upgrade/ { deny all; }

    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:

  2. 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.

  3. 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; do wp plugin list --path="$s" --skip-plugins --skip-themes --fields=name,version --format=csv 2>/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.

  4. 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
  5. 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:

    shell
    /usr/local/cpanel/cpanel -V
    /scripts/upcp --force

    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.

  6. 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:

    shell
    dnf update brotli brotli-libs
    grep -l "libbrotli.*(deleted)" /proc/*/maps 2>/dev/null | cut -d/ -f3 | xargs -r ps -o pid,comm -p

    Until then, block xmlrpc.php at the web server and install Patchstack’s must-use plugin that sets the cURL encoding to identity.

  7. 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.

Actions · priority 1 and 2

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

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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.

  6. 06

    The fixed CloudLinux kernel running

    uname -r at or above the table; the namespace sysctl still at 0 where it cannot be.

  7. 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.

  8. 08

    session.upload_progress.enabled at 0 on every SAPI

    Read from the interpreter, not the file, for every branch.

  9. 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. 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

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.

One site, one worrying result

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.