PHP2Shell: patch before you read this
PHP2Shell: patch before you read this
Two critical RCEs, a broken embargo, and the 12 links worth your time this week.
Hey 👋
If you run PHP in production, do one thing before you keep reading: check your version.
You want 8.5.12, 8.4.27, 8.3.36 or 8.2.35. Anything older is exposed to PHP2Shell.
Done? Good. Because this week was a mess.
What happened
On Monday, October 20, two CVE IDs started circulating on Hacker News and social media. Two days before the planned disclosure.
The details were half wrong (wrong release time, a CVSS of 10.0 when the real score is 9.2), but the noise was enough. The PHP security team pulled the release forward and shipped the fix on Tuesday at 14:00 UTC.
And then it got worse:
A security firm accidentally published a proof-of-concept video.
Chainguard shipped patched images more than six hours before the coordinated release, breaking the embargo.
Amazon says its honeypots saw an exploit attempt on October 17. Four days before anyone was supposed to know.
The bugs
CVE-2026-109618: running out of memory can leave request data half-built, and cleanup treats it as valid.
CVE-2026-109619: state from one request survives after it’s freed, and the next request on the same worker uses it.
Both mean unauthenticated remote code execution. PHP-FPM, php-cgi, FrankenPHP, LiteSpeed… all affected. mod_php is the worst case, because the exploit runs before your application code. Palo Alto counts 22.6 million exposed instances.
On Thursday a third one arrived (CVE-2026-115560, session upload progress). This one only hits unusual configs, but it’s worth a look.
The part that stuck with me
According to the PHP Foundation, the root cause of the first bug was spotted in a 2024 external audit. The fix stalled for months because the security team couldn’t agree on the trade-offs.
Two years. That’s the real story.
To their credit, they’re changing it: decisions by majority vote, more paid engineers, sanitizer builds and AI-assisted validation. They’re also asking companies and hosts to fund the work. If your business runs on PHP, that’s worth reading.
One practical note: if you deploy with Docker, a patched host doesn’t help you. Rebuild your images. And if you’re still on PHP 8.1 or older, there’s no official release for you. Only source backports.
Read more:
Now, the links. Fewer this week, but every one earns its spot.
🔒 Security week (it wasn’t only PHP core)
Critical Token Guard Auth Bypass Fixed in Laravel 13.29 and 12.68
Using the token API guard on MySQL or MariaDB? An unauthenticated attacker could log in as any user without knowing their token. Check your version today.
AI Agents Broke Into 100+ Sites at About $50 Each. The Confirmed One Used Old PHP Flaws
One operator, a short prompt and ~$5,000 in tokens. The verified breach used an exposed memcached, unserialize() on session data and gadgets from legacy Zend code. Old bugs, new attackers.
How the PHP Security Team Handles Your Reports
Published one week before PHP2Shell. Reads very differently now. Good context for everything above.
Drupal issues urgent security fixes for a remote code execution flaw
Critical RCE in Drupal core’s Field UI module, plus fixes for Link and Navigation. If you maintain a Drupal site, this one is for you.
🟥 Laravel
Rule Builders for Every Validation Rule in Laravel 13.36
No more required_without:email strings your editor can’t autocomplete. Plus DB::olap() for big reports on PlanetScale and an opt-in reset of sticky DB connections between queue jobs.
Pin a Legacy Laravel Controller With Golden-Master Tests, Then Extract the Use Case
A 300-line controller, zero tests, and a new feature to ship. The best refactoring guide I read this week.
Why One Redis Key Per Counter Is Wasting Your Laravel App’s Memory
A small change in how you store counters, with code you can copy today.
🐘 PHP
PHP Enums From the Query String: tryFrom() vs from()
“Just use tryFrom()” is only half the answer. With int-backed enums it breaks in ways you won’t expect. Tested on PHP 8.3.
What we learned running WordPress on Cloudflare Workers
PHP compiled to WebAssembly, running inside a Worker. No server. It sounds like a joke, and it works.
🎵 Symfony
Symfony 8.0 Got 8 Months of Support. Your Upgrade Bill Depends on Where Symfony Lives
Released in November 2025, unmaintained by July 2026. If you picked a non-LTS version, read this before planning your next sprint.
Three security fixes (HttpFoundation, ExpressionLanguage and Yaml), Symfony UX 3.6, a new JsonSchema component and a preview of 8.2. Yes, more patching.
From 14s to 1.8s: A Symfony Cold Start Autopsy
A SymfonyCon Warsaw talk about cutting a Cloud Run cold start from 14 seconds to 1.8. Almost all the time went to a cause the profiler never showed.
That’s it for this week. Go update PHP. 😉
If this email was useful, forward it to the teammate who is still on 8.1. They need it more than you.
See you next week,
Víctor
Invite your friends and earn rewards
© 2026 Víctor Falcón 🤟
548 Market Street PMB 72296, San Francisco, CA 94104