Skip to content
OA.

Home / Blog / Security

› Security

PHP2Shell: Understanding the Critical PHP Vulnerabilities and What You Should Do Now

By Ohene Adjei Effah · 6 min read

PHP2Shell: Understanding the Critical PHP Vulnerabilities and What You Should Do Now

On October 20th, technical details and working proof-of-concept code for two serious PHP vulnerabilities leaked online before the PHP team had finished preparing its fixes. This forced an accelerated response: the PHP project released emergency patches today, October 21, 2026, at 14:00 UTC.

The two vulnerabilities were tracked as CVE-2026-109618 and CVE-2026-109619, and the security community nicknamed them collectively as "PHP2Shell". Security firms, including watchTowr, are already observing active exploitation attempts in the wild.

Why this is serious

Both bugs are rated 9.2 out of 10 on the CVSS v4.0 severity scale. It allows an attacker to send a crafted HTTP request to your server and get it to run without needing to log in, guess a password, or know anything specific about your application. The PHP team has confirmed this is possible on default configurations.

The two vulnerabilities, simply explained

CVE

What goes wrong

CVSS

CVE-2026-109618

When PHP runs out of memory mid-request, it leaves things in a broken state. A later cleanup step treats that broken state as valid, which an attacker can exploit to run arbitrary code.

9.2

CVE-2026-109619

PHP can hold onto request-specific data after the memory backing it has been freed. The next request handled by that same worker process may read or branch on that stale, freed memory, a classic heap use-after-free that leads to code execution.

9.2

The common thread is that both bugs involve PHP leaving its memory in a bad state when a request ends abnormally and that bad state becoming exploitable by the next request.

Who is affected?

Any server that runs PHP and accepts web requests is affected. This includes every common setup: PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP, and LiteSpeed. The PHP team considers Apache mod_php to be at the highest risk, since exploitation can happen before your application code even runs, on a completely default configuration.

The fixed versions released today are:

PHP 8.5.12PHP 8.4.27PHP 8.3.36PHP 8.2.35

PHP 8.1 and older

PHP 8.1 and all earlier versions are end-of-life and will not receive official binary patches. The PHP project has published source-only backports for 7.4, 8.0, and 8.1, but you will not get pre-built packages for those. If you are still on an EOL version, upgrade to a supported branch, and this vulnerability makes that urgent.

What to do, step by step

  1. Patch. This is the only real fix.

    Update to the patched version for your branch (listed above) and restart all PHP workers, FPM pools, Apache, whatever you use. Don't just check the CLI version; verify the version your web server is actually running:

    php-fpm8.4 -i | grep "PHP Version"

    Better yet, check from inside the web server itself with a small script, since CLI and the web SAPI can differ.

  2. While you wait to patch: disable session upload progress

    Setting this blocks a confirmed attack path for CVE-2026-109619. Set it in php.ini, your FPM pool config, or your Apache/Nginx config, not via ini_set() in your app, since that runs too late:

    session.upload_progress.enabled = Off

    Then restart all workers. This is a partial mitigation, not a full fix, as it doesn't cover all exploitation paths or CVE-2026-109618. Patch as soon as you can.

    For PHP 8.5 specifically, also add:

    fatal_error_backtraces = Off

    Most applications will not break from disabling this feature. Laravel, WordPress, and virtually all modern frameworks handle upload progress on the client side with JavaScript. If your code doesn't reference PHP_SESSION_UPLOAD_PROGRESS anywhere, you won't notice the change.

  3. For CVE-2026-109618: set memory_limit to -1

    This sounds counterintuitive, but the official interim mitigation for the out-of-memory bug is to remove the memory limit, not raise it. Setting memory_limit=-1 means PHP never hits an OOM condition mid-request, which eliminates the trigger for this vulnerability. Set it where applications can't override it, and that will be in your FPM pool or Apache config:

    ; In your FPM pool config (www.conf or similar):
    php_admin_value[memory_limit] = -1
    
    ; Also tighten post_max_size to limit request body size:
    php_admin_value[post_max_size] = 8M   ; 32M if you need file uploads

    If you run containers or cgroups, use those as availability guardrails; they can kill only the affected worker if memory gets out of hand, without exposing the vulnerability.

  4. A few more things worth doing

    These won't fix the vulnerabilities, but they reduce your exposure and help you catch exploitation attempts early:

    • Monitor for unusual multipart POST traffic or spikes in failed requests — scanners and exploit attempts tend to generate noise before they succeed.

    • If you have a WAF, consider restricting multipart form submissions to routes that actually need file uploads.

    • Ensure session.use_strict_mode = On while you're reviewing your PHP config.

    • For EOL servers you can't patch immediately, consider temporarily isolating them from direct internet traffic behind a reverse proxy.

  5. Confirm your config is actually applied

    Config changes are easy to make in the wrong file. After any change, verify it took effect under the web server, not just the CLI:

    php-fpm8.4 -i | grep "session.upload_progress.enabled"
    php-fpm8.4 -i | grep "memory_limit"

    A small PHP script that calls phpinfo() or ini_get('session.upload_progress.enabled') served through your web server is even more reliable.

A note on fake exploits circulating online

Because details leaked before the patch, a lot of code claiming to exploit PHP2Shell appeared online quickly. Security researchers have noted that most of it is fake or unverified. That doesn't mean the vulnerabilities aren't real — they are, and exploitation has been observed — but don't panic-test code from unknown sources claiming to be PoCs.

The bigger picture

The early leak of these vulnerabilities created an uncomfortable situation: server operators had a window where attackers knew more than defenders. That window is now smaller since patches exist, but it's not zero, as applying a PHP update across production infrastructure takes time, and the bugs are being actively probed.

If you manage PHP yourself, treat this as a priority update. If you're on managed hosting, check your provider's status page — most major cloud platforms and hosting providers are pushing updates today. Distribution packages (Debian, Ubuntu, RHEL, Alpine) and Docker base images may take a few hours to a day to catch up, so check your specific vendor.

Bottom line

Patch to PHP 8.5.12, 8.4.27, 8.3.36, or 8.2.35 and restart your workers. While you're getting there: set session.upload_progress.enabled = Off, set memory_limit = -1 via admin config, and restart workers. Check php.net for official advisories, and check your hosting provider or distribution for pre-built packages.

Related posts