Cookie settings

Decide per category. You can come back here at any time from the footer.

NecessaryAlways on

Signing in, your language and theme, and remembering this very choice. The site does not work without them, so there is nothing to switch off.

Google Analytics, to see which pages get used and where people give up. Off until you turn it on, and the data is never passed on to Google Ads.

Aderlo Cloud
Sign inGet started

PHP2Shell (CVE-2026-109618 and CVE-2026-109619): what the PHP flaws are, who is affected and what to do today

Grzegorz Ciupek · Updated 21 October 2026 · 12 min read

PHP2Shell is a pair of critical flaws in the PHP interpreter itself — CVE-2026-109618 and CVE-2026-109619, both rated CVSS 9.2 — that let an unauthenticated attacker run code on the server and read PHP process memory holding passwords and API keys. The only complete fix is updating PHP to 8.5.12, 8.4.27, 8.3.36 or 8.2.35 (released on 21 October 2026) and restarting every PHP process; updating WordPress or plugins does not remove the flaw.

What happened on 21 October 2026

On 21 October 2026 the PHP project released 8.5.12, 8.4.27, 8.3.36 and 8.2.35, fixing two critical vulnerabilities in the language core that their discoverers named PHP2Shell. The research came from Wiz Research, OpenAI Codex Security and Calif. Details leaked before the planned disclosure, so the fixes shipped at 13:50 UTC, and security vendors reported the first exploitation attempts the same day.

National CERTs issued warnings; CERT Polska (bulletins 195/2026 and 196/2026) urged immediate updates and, where that is impossible, interim php.ini changes. PHP runs roughly 70% of websites, including WordPress, WooCommerce, Joomla, Drupal, Moodle, Nextcloud, Laravel, Symfony and MediaWiki.

This is not a plugin or theme bug. PHP itself is vulnerable, so the attack works even against a one-line "Hello World" page. Updating WordPress, Joomla or your store changes nothing — the PHP runtime underneath has to be updated.

The two flaws in plain language

CVE-2026-109618CVE-2026-109619
NameRCE via out-of-memory (OOM) corruptionRCE via stale global state
What breaksWhen PHP hits memory_limit while handling a request, it bails out with request data only partly initialised. Request cleanup then treats the half-built data as valid.Some request state (errors, session, objects) survives after its memory is freed. The next request on the same worker uses the freed memory (use-after-free).
How it is triggeredA crafted multipart form: no Content-Length, unbounded part headers, empty file fields, deeply nested field names.A fatal or out-of-memory error, then a feature that reads the stale state — e.g. session upload progress (on by default) or fatal_error_backtraces in PHP 8.5.
ImpactCode execution as the PHP worker userMemory disclosure or code execution
ScoreCVSS 4.0: 9.2 (critical)CVSS 4.0: 9.2 (critical)
Based on PHP advisories GHSA-w8hw-w9fx-j79w and GHSA-6wmf-4rv5-p3rp, as of 21.10.2026.

The less discussed consequence is the worst one: process memory disclosure. PHP memory holds database passwords, session tokens, payment gateway API keys and certificates, including those of other requests. The researchers demonstrated reading it application-agnostically and without running any malicious code, which makes it hard to spot with tools that look for infections.

Who is affected: versions and server setups

Practically every PHP version from 5.4 up is affected, in every setup that serves web traffic: Apache mod_php, PHP-FPM, php-cgi, FrankenPHP and LiteSpeed (LSAPI). The PHP team rates mod_php as the highest risk, with a demonstrated unauthenticated takeover on default settings before any application code runs.

PHP branchVulnerableFirst fixed releaseNotes
8.5< 8.5.128.5.12also set fatal_error_backtraces = 0 if you cannot update yet
8.4< 8.4.278.4.27active support
8.3< 8.3.368.3.36security fixes only
8.2< 8.2.358.2.35end of life on 31.12.2026
8.1, 8.0, 7.4allno PHP releasedistribution/LTS vendor patches or minimal source backports only
5.x, 7.0–7.3allno PHP releaseas above — move to 8.3 or 8.4
Source: PHP security advisory, 21.10.2026.

Linux distributions (Debian, Ubuntu, RHEL, AlmaLinux, CloudLinux) often backport the fix into an older version number. Ubuntu's "PHP 8.1.2" can be safe while a source-built "PHP 8.3.35" is not. The package changelog decides, not the version string.

How to check whether your site is vulnerable

  1. Find the PHP version that serves the site.

    In WordPress: Tools → Site Health → Info → Server. In your hosting panel: the domain's PHP settings. On the command line: php -v (the CLI version can differ from the one serving the site).

  2. Compare it with the table above.

    8.2–8.5 below the fixed release is vulnerable. For 8.1 and older, ask your vendor whether the package carries a backport.

  3. For distribution packages, check the changelog.

    RHEL, AlmaLinux, CloudLinux: rpm -q --changelog php-common | grep -E "CVE-2026-10961[89]". Debian, Ubuntu: apt changelog php8.3-common | grep -E "CVE-2026-10961[89]". No output means no fix.

  4. Inventory everything that embeds PHP.

    Not just websites: Docker images (e.g. php:8.3-fpm), admin panels, phpMyAdmin, Roundcube, newsletter systems, appliances. Each has its own PHP and needs its own update.

What to do: updating step by step

  1. Install the fixed PHP.

    From php.net sources or your distribution: dnf update php* / apt upgrade. CloudLinux: yum update "alt-php*" (and ea-php* on cPanel). The volunteer-run Remi repository had no update on release day; the PHP team advised switching to distribution packages or building from source.

  2. Restart every PHP process.

    PHP-FPM, Apache with mod_php, LiteSpeed lsphp processes, long-running workers (Laravel queues, Swoole, RoadRunner). Without a restart the old, vulnerable code keeps running in memory.

  3. Update container images.

    Pull the new base image, rebuild your images and recreate containers. For packaged apps, wait for the vendor's release.

  4. PHP 8.1 and older: plan the move.

    The PHP project will not ship fixes for them. Use a vendor backport for the transition, then move the site to PHP 8.3 or 8.4.

  5. Verify after updating.

    The PHP version the site actually sees, error logs, forms and uploads. The fix adds a new hard memory ceiling: a process that crosses it exits immediately without running shutdown functions — test memory-hungry imports and exports.

If you cannot update right away: php.ini mitigations

The PHP team lists settings that block the confirmed attack paths. None of them makes an installation safe; they bridge the gap until you update. Put them in the main php.ini or the FPM pool (php_admin_value), not in ini_set() or .user.ini, which apply too late, after the request has been parsed.

; php2shell — temporary, until PHP is updated
session.upload_progress.enabled = 0   ; CVE-2026-109619, confirmed path
fatal_error_backtraces = 0            ; PHP 8.5 only
post_max_size = 32M                   ; 8M if the site takes no uploads
upload_max_filesize = 24M             ; always below post_max_size
max_input_nesting_level = 16
display_errors = 0
expose_php = 0
  • session.upload_progress.enabled = 0 blocks the confirmed CVE-2026-109619 path. It is on by default and almost no site uses it; the PHP team suggests keeping it off after patching too.
  • fatal_error_backtraces = 0 (PHP 8.5) blocks the second confirmed path of the same flaw.
  • A low post_max_size — 8M without uploads, 32M with them — limits how much memory one request can consume (CVE-2026-109618). Enforce similar limits at the web server or proxy, including for requests without a Content-Length.
  • memory_limit = -1 removes the limit the OOM attack relies on, but hands memory control to the OS. Use it only with a cgroup limit (container, LVE, memory.max) and a setting applications cannot override, and restore a finite limit after patching.
  • Do not use RLIMIT_AS or RLIMIT_DATA as a substitute memory limit — they can trigger the very same vulnerable path.
  • Remove deprecated per-directory settings (e.g. php_value in .htaccess with auto_detect_line_endings, legacy assert.*, session.sid_length on 8.4+, or report_memleaks=0 on 8.5). Diagnostics they emit before the request starts are a CVE-2026-109619 trigger; hiding them with error_reporting or @ does not help.

Will a WAF, Cloudflare or the host firewall protect me?

Not on their own. WAF vendors (Cloudflare, Imperva, Akamai, Imunify360) shipped rules for the known shape of the public exploit on day one. That virtual patch stops scanners and the first wave, but a slightly different request gets through — CloudLinux noted that its first ruleset only logged the pattern on LiteSpeed servers instead of blocking it. Keep the WAF on and updated as an extra layer; an unpatched PHP behind Cloudflare is still vulnerable, and memory disclosure need not look suspicious at all.

How to spot exploitation attempts in logs

  • unusually large or malformed PHPSESSID cookies in responses,
  • unusual multipart requests followed by memory-limit errors or bursts of HTTP 500,
  • unexplained PHP worker crashes and restarts (child exited on signal in FPM logs, dying lsphp).
# 500 responses to multipart requests (forms with files) — look for bursts from one IP
grep -E '"POST [^"]*" 500 ' access_log | awk '{print $1}' | sort | uniq -c | sort -rn | head

# Memory-limit errors and crashing PHP workers
grep -E 'Allowed memory size of|Out of memory|exited on signal|child .* exited' error_log | tail -50

# Unusually long PHPSESSID cookies (in logs that record them)
grep -oE 'PHPSESSID=[^; "]{80,}' access_log | head

Absence of these signals does not prove a server is clean — some attacks read memory without leaving a clear trace — and application logs usually show nothing, because the vulnerable code runs below the application.

After patching: what else to secure

  1. Change the database password

    and update wp-config.php / the app's .env.

  2. Regenerate WordPress keys and salts

    — this logs everyone out and invalidates stolen cookies.

  3. Rotate API keys

    for payment gateways, couriers, SMTP, mailing systems and other integrations stored in configuration.

  4. Review admin accounts and recently changed PHP files

    (e.g. find . -name "*.php" -newermt 2026-10-20) and run a malware scan.

  5. Clean up temporary settings

    restore a finite memory_limit, keep session.upload_progress.enabled = 0, set expose_php = 0.

  6. Make updates routine

    PHP 8.2 reaches end of life on 31 December 2026. A regular PHP update cadence and an inventory of where PHP runs turn the next response from days into hours.

What Aderlo Cloud did

Aderlo Cloud is WordPress and WooCommerce hosting on LiteSpeed and CloudLinux servers, where customers choose PHP from 7.4 to 8.5. On the evening of 21 October 2026 the Aderlo Cloud team did the following on every server running PHP:

  • The server's native PHP 8.3 updated to 8.3.36 on the day the fix was released.
  • php.ini mitigations on all 14 customer PHP versions (5.4–8.5): session.upload_progress off, and fatal_error_backtraces off on PHP 8.5, in the main php.ini that applies before request parsing — verified from inside customer accounts, not from the admin account.
  • An audit of deprecated per-directory PHP settings in .htaccess, .user.ini and account settings: no site sets directives that trigger CVE-2026-109619 before the request starts.
  • Imunify360 web application firewall with the 21 October 8.85 ruleset that recognises the PHP2Shell tool.
  • Automatic installation of CloudLinux fixes for selectable PHP versions: every 20 minutes the server checks for patched packages, installs them, restarts PHP and compares a sample of customer sites on each PHP version before and after; if any site starts failing, the update rolls back by itself and the team is alerted.
  • Containerised apps (e.g. NetSendo) received the same mitigations; their images are updated once the vendor ships a release on fixed PHP.
WordPress hosting at Aderlo Cloud →

Frequently asked questions

Does updating WordPress or plugins protect against PHP2Shell?
No. The flaw is in the PHP interpreter. The researchers took over the latest WordPress, Drupal and Joomla. Update PHP to 8.5.12, 8.4.27, 8.3.36 or 8.2.35 (or a vendor-patched package) and restart PHP processes.
Does the attacker need an account on the site?
No. The demonstrated attacks needed no login, just an HTTP request. Some variants require particular conditions, which is why the score is 9.2 and not 10.
Will PHP 7.4 and 8.1 get a fix?
Not from the PHP project, which no longer supports them. The PHP team published minimal source backports for 7.4, 8.0 and 8.1, and distributions and LTS vendors ship their own patched packages. Long term, move the site to PHP 8.3 or 8.4.
Do I need to change passwords after updating?
If logs show signs of attempts or the server stayed unpatched for long — yes. CVE-2026-109619 can disclose PHP process memory holding database passwords, API keys and session tokens.

Sources