php2shell: Is your PHP server open to takeover?
On 21 October 2026 PHP fixed two critical bugs that let an attacker run their own code on your web server without logging in, using nothing but crafted HTTP requests. Researchers demonstrated it against default installs of WordPress, Drupal, Joomla, Magento, Nextcloud, Laravel and more. Updating your plugins or CMS does not help. Only patching PHP itself fixes it.
Am I vulnerable? Three quick checks
Run these on the server that hosts your website (SSH or your hosting panel's terminal). Paste the output of step 1 into the checker below to get an instant answer.
01Check your PHP version
The quickest test. Run it on the web server, not your laptop:
php -v
The command-line PHP can be a different build from the one serving your site. Check the web-facing binary too:
# PHP-FPM (nginx, most modern hosts) for b in /usr/sbin/php-fpm* $(command -v php-fpm); do "$b" -v | head -1; done # Apache mod_php: which PHP module is loaded apachectl -M 2>/dev/null | grep -i php
No shell access? Ask your host, or look in cPanel → MultiPHP Manager, Plesk → PHP Settings, or WordPress → Tools → Site Health → Info → Server.
02Using Debian, Ubuntu, RHEL or Alma packages? Check the changelog
Distributions often backport the fix without changing the version number. A version like 8.1.2-1ubuntu2.x can be patched. Confirm it in the package changelog:
# Debian / Ubuntu apt changelog "php$(php -r 'echo PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;')-common" 2>/dev/null | grep -E "CVE-2026-10961[89]" # RHEL / Alma / Rocky / CentOS Stream rpm -q --changelog php-common | grep -E "CVE-2026-10961[89]"
If both CVE IDs appear, your package is patched. If nothing prints, treat the server as vulnerable.
03Check your exposure settings
These settings decide which attack paths are reachable before you patch:
php -i | grep -E "^(memory_limit|post_max_size|upload_max_filesize|session.upload_progress.enabled|fatal_error_backtraces) "
The output below is the default, and it is exposed: memory_limit => 128M with session.upload_progress.enabled => On. The web SAPI can use a different php.ini from the CLI. For a true picture, open a temporary phpinfo() page and delete it straight after.
Runs entirely in your browser. Nothing is sent anywhere.
Fixed versions
The official fix is in the PHP security release of 21 October 2026. Upgrade to at least these versions:
| Branch | Vulnerable | Fixed in | Status |
|---|---|---|---|
| 8.5 | < 8.5.12 | 8.5.12 | Supported |
| 8.4 | < 8.4.27 | 8.4.27 | Supported |
| 8.3 | < 8.3.36 | 8.3.36 | Security fixes only |
| 8.2 | < 8.2.35 | 8.2.35 | End of life on 31 Dec 2026 |
| 8.1 / 8.0 / 7.4 | All | No official release | EOL. Minimal source backports exist; use a vendor or LTS package, or upgrade |
| 7.3 and older | Assume all | None | EOL. Upgrade |
Typical patch commands
# Debian / Ubuntu sudo apt update && sudo apt install --only-upgrade 'php*' sudo systemctl restart 'php*-fpm' apache2 2>/dev/null # RHEL / Alma / Rocky sudo dnf upgrade 'php*' sudo systemctl restart php-fpm httpd 2>/dev/null # Docker: rebuild on the patched official image tag docker pull php:8.4-fpm && docker compose up -d --build
After patching, restart every PHP worker (FPM pools, Apache) and run php -v again.
Shared hosting or managed WordPress?
- Your host controls the PHP binary. Open a ticket and ask: "Is my account's PHP patched for CVE-2026-109618 and CVE-2026-109619?"
- Switch to the latest PHP version offered in your control panel.
- Updating WordPress, Drupal, Joomla or plugins does not fix this. The bug is in PHP.
- Appliances and third-party products that bundle PHP need their own vendor patch.
Can't patch today? Temporary mitigations
PHP's advisory is explicit: "There are no complete mitigations, updating is the only safe choice." These settings reduce exposure to the known attack paths while you schedule the upgrade.
CVE-2026-109618: OOM corruption
; php.ini, or php_admin_value in the FPM pool memory_limit = -1 post_max_size = 8M ; or 32M if you need uploads upload_max_filesize = 6M ; keep below post_max_size
- With
memory_limit=-1one request can use all RAM. Cap memory with a container or cgroup limit instead. - Do not use
RLIMIT_AS/RLIMIT_DATA. They trigger the same vulnerable allocation failure.
CVE-2026-109619: stale global state
; php.ini, FPM pool, or server config session.upload_progress.enabled = 0 fatal_error_backtraces = 0 ; PHP 8.5 only
- Set these in
php.ini, the FPM pool or the server config.ini_set()and FPM.user.iniare not enough. - Restart every PHP worker afterwards.
What php2shell actually is
Ryan Austin at Calif found it. The attacker sends a crafted multipart/form-data request that drives PHP past its memory_limit at exactly the wrong moment. The fatal "out of memory" error interrupts PHP half-way through updating its internal data. One example is a hash-table bucket that is counted but not yet initialised.
During request cleanup PHP treats that broken data as valid (CVE-2026-109618). Related paths in session upload-progress and the unserialize decoder leave dangling pointers that survive into the next request on the same worker (CVE-2026-109619). Both lead to memory corruption and remote code execution.
It works against arbitrary PHP scripts under Apache mod_php and PHP-FPM with default settings. The 128 MiB memory_limit and 8 MiB post_max_size defaults are part of the attack.
Shown exploitable (pre-auth) in research
- WordPress 7.1.2
- Drupal 11.4.3 • Joomla 6.1.4
- Magento 2.4.9
- Nextcloud 35.0.1 • Roundcube 1.7.4
- MediaWiki 1.46.2 • phpMyAdmin 5.2.3
- Laravel 13.11 • Symfony 8.1 • WHMCS
Huntress counts PHP-FPM, mod_php, php-cgi, FrankenPHP and LiteSpeed as at risk: "all PHP installations serving web requests".
Were you already hit? Signs of compromise
No official IOCs had been published at the time of writing. A successful php2shell attack ends in code running as your web user, so look for what attackers do next:
01Shells spawned by PHP
ps -eo pid,ppid,user,cmd --forest | grep -A3 -E "php-fpm|apache2|httpd" | grep -E "sh -c|bash|python|perl|curl|wget|nc "
Watch for php-fpm, apache2 or httpd starting sh, bash, curl, wget or nc, and for reverse-shell patterns like /dev/tcp/, mkfifo or fsockopen.
02New or changed files in the web root
find /var/www -type f -newermt "2026-10-20" \( -name "*.php" -o -name "*.phtml" -o -name ".htaccess" \) -ls
03Persistence
crontab -l -u www-data; ls -la /etc/cron.* /var/spool/cron* 2>/dev/null grep -E "/bin/(ba)?sh" /etc/passwd; last -n 20
04Odd large multipart POSTs
In your access logs, look for bursts of large multipart/form-data POSTs to ordinary pages, each followed by 500 errors or PHP "Allowed memory size exhausted" fatals in the error log.
grep -h "Allowed memory size" /var/log/php*fpm*.log /var/log/apache2/error.log /var/log/nginx/error.log 2>/dev/null | tail -50
Not sure? Let an offensive security expert check it for you.
Most small businesses don't have someone who can tell whether a server is actually safe, or already compromised. We verify the way an attacker would, and give you a clear yes or no with the exact fix.
- Confirm the real PHP build and SAPI behind each site, not just the CLI
- Check the distro backport and php.ini mitigations on every host
- Look for compromise: webshells, persistence, suspicious processes
- Hands-on patch and mitigation guidance for your exact stack
- Written confirmation for your management, customers or insurer
Confidential. NDAs available. Karim personally reviews every request.
Emergency Triage Call
30 minutes, screen-share. We check your version, config and quick compromise signs together, and you leave with a clear action plan.
php2shell Verification
We check every PHP host you name for patch status, effective mitigations and indicators of compromise, then hand you a short written report.
External Exposure Snapshot
php2shell won't be the last critical bug. Map everything you expose to the internet before the next one. Request it →
Timeline
- 2004Stefan Esser shows the first remote bug triggered by PHP's memory limit
- 2020PHP bug #78876 reported
- 2024OSTIF / Quarkslab audit flags a related issue (not shown exploitable)
- 01 Aug 2026Calif finds several independent paths to RCE
- 11 Aug 2026First bug reported to PHP; coordinated disclosure begins
- 15 Aug 2026PHP confirms the proof of concept works
- 21 Aug 2026Second bug reported
- 20 Oct 2026Advance notice; vulnerability details leak ahead of release
- 21 Oct 2026PHP 8.5.12 / 8.4.27 / 8.3.36 / 8.2.35 released
FAQ
My site is behind Cloudflare or a WAF. Am I safe?
Not reliably. A WAF may block known payloads, but the attack uses normal-looking multipart uploads to normal pages. Patch PHP anyway.
I don't use file uploads. Does this affect me?
Yes. PHP parses multipart request bodies before your code runs, so any PHP script reachable over HTTP is a target.
php -v shows an old version but my distro says it's patched.
That's normal for Debian, Ubuntu and RHEL-family packages. Confirm with the changelog commands in step 2.
We're on PHP 7.4 / 8.0 / 8.1. What now?
The PHP project won't ship official releases for these. Use a backport from your distribution or LTS vendor, apply the mitigations above today, and plan the upgrade to 8.3 or newer. We can help you prioritise.
Do I need to update WordPress or my plugins?
No. WordPress.org has said no WordPress update is needed. The fix is the PHP runtime.
Sources
- Calif, original research by Ryan Austin: calif.io/php2shell
- PHP security advisory, 21 Oct 2026: php.net/archive/2026.php
- CVE-2026-109618 (GHSA-w8hw-w9fx-j79w) • CVE-2026-109619 (GHSA-6wmf-4rv5-p3rp)
- Huntress rapid response: huntress.com
Last updated 22 October 2026. This page will be updated as vendors publish more detail.