php2shell.site active development
php2shell check — patch & mitigation status for CVE-2026-109618 / CVE-2026-109619, two critical unauthenticated remote-code-execution bugs in PHP, for URLs you are authorized to test. All verdict logic runs locally in your browser — the server only relays raw HTTP facts.
advisory out now — update PHP php.net, 21 Oct 2026: Critical remote code execution vulnerabilities, update now · details ▾
Fixed in PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35
(source,
Windows;
Linux distributions and LTS vendors got the patches in advance — check your vendor).
At risk: every PHP installation serving web requests — PHP-FPM, Apache mod_php, php-cgi,
FrankenPHP, LiteSpeed; highest for mod_php, where an unauthenticated request can trigger the attack
before any application code runs.
CVE-2026-109618 (GHSA-w8hw-w9fx-j79w):
RCE via out-of-memory corruption during request setup.
CVE-2026-109619 (GHSA-6wmf-4rv5-p3rp):
RCE via stale global state reused by a later request on the same worker.
PHP 8.1 and older get no release from the PHP project: use your vendor’s backport or upgrade;
minimal source backports exist for
7.4,
8.0 and
8.1.
Using rpms.remirepo.net? It has no update today — switch to distribution packages or build from source.
If you cannot update immediately (reduces exposure, does not make PHP safe)
CVE-2026-109618 (OOM corruption):
memory_limit=-1, set where applications can’t override it (e.g.php_admin_valuein the FPM pool or Apache config); make sure no pool/directory/app setting brings a finite limit back.- Low
post_max_size:8Mwithout file uploads,32Mwith them; keepupload_max_filesizebelow it. Also limit decoded request size, field count, multipart part count, header count and nesting depth at the web server / proxy — including requests without a usable Content-Length. - Container / cgroup memory limit as an availability boundary (ideally killing only the affected worker). Do not use
RLIMIT_AS/RLIMIT_DATA— they can cause the vulnerable allocation failure.
CVE-2026-109619 (stale global state):
session.upload_progress.enabled=0in php.ini, the FPM pool or server config (applies before request parsing), then restart every worker. Not viaini_set()or FPM.user.ini. Blocks the confirmed session paths only.- PHP 8.5:
fatal_error_backtraces=0and restart every worker (blocks the confirmed backtrace path only). - Remove invalid/deprecated per-request settings that emit diagnostics before initialization — hiding them (
error_reporting,display_errors,@) does not help. - Fix attacker-reachable fatal errors and execution timeouts (callbacks, upload/import processing, cleanup).
DIY: Run the curl test script yourself
Want to run the exact same inert checks yourself directly from your terminal or CI? Below is the curl test script representing the 7 requests (1 GET + urlencoded & multipart across POST, PUT, and PATCH). It never sends upload-progress fields or file parts, so it is safe to run on authorized targets.
Bash / curl script
How to interpret the output:
- X-Powered-By / Server header: Look for PHP version info (fixed releases: 8.2.35+, 8.3.36+, 8.4.27+, 8.5.12+).
- Multipart 403 / 406 while urlencoded succeeds (200/302/405): Multipart is blocked by WAF/CDN/web server rule before PHP processes it (MITIGATED — UPDATE STILL NEEDED).
- Multipart 200 / 3xx: Multipart request body reaches the application (ASSUMED VULNERABLE if unpatched).
- All 405 Method Not Allowed: if the 405 responses carry no PHP signs (no PHPSESSID cookie, no X-Powered-By) the server refused before PHP (MITIGATED — UPDATE STILL NEEDED, or NO PHP DETECTED without any PHP indicators). A 405 that sets a PHP session cookie came from PHP itself, after it read the upload (ASSUMED VULNERABLE).