PHP's second session RCE in three days is real — and PHP itself says you can probably ignore it.
CVE-2026-115560: session serialize-handler confusion. The ‼️ BREAKING unpatched RCE ‼️ repost got all three lines wrong. The actual php.net advisory (Oct 23): informational advisory, regular release cycle, trigger setup "unlikely in practice". One more case of the repost being cheaper than the read.
The combo — all three legs required:
1.
The detection artifact is beautiful: the read logs
The kit also ships
session.serialize_handler = php_binary or php_serialize in configuration
2. application code switches it back to php at runtime with ini_set() before session_start()
3. session.upload_progress.enabled still on
The mechanism: the upload-progress entry is written under one grammar and parsed under another. The php handler splits entries at the first | — and the attacker chose the key name. p|O:8:"Gadget":… and your unserialize() runs attacker bytes.
I built the lab and confirmed the injection on PHP 8.5.10 — two requests, no race (upload_progress.cleanup=0 parks the poisoned entry in the store, request 2 can come hours later):
text
[1] upload POST — writes the progress entry under the crafted key…
[2] read GET — ini_set to `php`, session_start()…
> DemoVuln::__wakeup — attacker-controlled unserialize executed, note=pwned-1
> read OK — session keys: []
RESULT: INJECTION CONFIRMEDsession_start(): Failed to decode session object — the decoder chokes on the bytes trailing the injected object and destroys the session, after the gadget already ran. If your code must keep the runtime switch, alert on that warning line.
Run it yourself (local only, binds 127.0.0.1, no Docker — the PHP CLI built-in server is the whole stack):
bash
git clone https://github.com/slabbdev/php-cve-2026-115560-kit cd php-cve-2026-115560-kit && ./run.sh
audit-cve-2026-115560.sh — the advisory's decision tree as one command: config leg, runtime ini_set switch (tests/vendor excluded), **effective** config per SAPI (CLI proves nothing for php-fpm), branch check against the Oct 21 patched releases (8.5.12 / 8.4.27 / 8.3.36 / 8.2.35), exit codes 0/1/2 for CI, --json if you'd rather parse than read.
Already applied Tuesday's mitigation (session.upload_progress.enabled=0, GHSA-6wmf-4rv5-p3rp)? Keep it — php.net's exact words: *"keep it in place and no further action is needed."* Never switch handlers at runtime? You can keep the feature on. And remember: one ini file per SAPI — that's the trap I'd bet on.
Full write-up + the lab:
→ https://dev.to/slabb/the-breaking-unpatched-php-rce-that-wasnt-what-cve-2026-115560-actually-requires-2ema
php.netPHPPHP is a popular general-purpose scripting language that powers everything from your blog to the most popular websites in the world.
commit 1dc1076
It is important to note that this should not be conflated with "PHP2Shell." Previous vulnerabilities involved different attack vectors, and patches were released for specific versions of PHP; this new issue, however, requires a separate review of configurations and the…