Blog
A critical PHP vulnerability: what we did and what you should do
This morning, a critical vulnerability in PHP was disclosed. It allows an attacker to run code on your server without logging in. On a default PHP install. That's about as bad as it gets.
And attacks have already started.
So we dropped everything we were working on. In this post, I'll explain what we know, what we did to protect Flare, and what you can do for your own PHP apps.
A quick note before we start. This is a fast moving situation, and we wanted to get this post out as quickly as possible. That's why we wrote it with the help of AI. We checked it as well as we could, but some information might not be 100% correct. When in doubt, follow the official PHP announcements. We'll update this post as we learn more.
Update: October 21, 14:00 UTC
The PHP team published the security advisory and the patched releases. And it's worse than we thought.
What the advisory says
There are two bugs, and both let an attacker run code on your server without logging in:
- CVE-2026-109618: when PHP runs out of memory at the wrong moment, it can leave internal request data half set up. The cleanup code then treats that broken data as valid.
- CVE-2026-109619: some internal state from one request survives after its memory is freed. The next request on the same worker can then use it.
Every PHP install that serves web requests is at risk. That includes PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP and LiteSpeed. The risk is highest for mod_php. There, the PHP team saw an exploit work before any application code ran.
The part that worried us most? The PHP team says there are no complete mitigations. Updating is the only safe choice. Our three layers from this morning make an attack harder, but they don't stop it.
What we did
So we did what nobody likes to do. We took parts of Flare offline on purpose.
Since 13:48 UTC, nginx answers every request to the Flare website and dashboard with a static maintenance page. Those requests never reach PHP. We did the same for incoming error reports.
Here's what still works and what doesn't.
Still running:
- Receiving logs and traces from your apps
- Notifications by email, Slack and your other channels
Offline for now:
- Receiving errors from your apps
- The dashboard and your settings
- The Flare API and the MCP server
- Shared error links and links in our emails
- The website and the docs
Why stop errors but keep logs and traces? Error reports take a different route through our setup. That route hands the incoming request to PHP almost untouched, which makes it the riskiest one we have. Logs and traces don't go that way.
That does mean errors your apps send during this window won't show up in Flare. We know that hurts. It's a monitoring tool after all. But it's a better deal than leaving a door open on a server that holds your data.
What you should do
Update PHP now. The fixed versions are:
- PHP 8.5.12
- PHP 8.4.27
- PHP 8.3.36
- PHP 8.2.35
After updating, restart everything that runs PHP: PHP-FPM, Apache, Octane, Horizon and your queue workers. A worker that's still running keeps the old, vulnerable PHP in memory.
Still on PHP 8.1 or older? The PHP team has no release for you. They did publish small source backports for 7.4, 8.0 and 8.1, so you can build PHP yourself. Or ask your LTS vendor. Upgrading stays the real fix.
Do you install PHP from rpms.remirepo.net? That repo won't get updates today. The PHP team suggests switching to your distribution's packages or building from source.
Can't update right away?
The advisory lists a few things that make an attack harder. None of them make you safe.
Set them in php.ini or your PHP-FPM pool, then restart every worker. ini_set() and .user.ini files kick in too late, so they don't help here.
; Only fix is updating. These only make an attack harder.
; Turn off upload progress tracking (blocks the known session route)
session.upload_progress.enabled = 0
; PHP 8.5 only: blocks the known fatal error backtrace route
fatal_error_backtraces = 0
; Keep request bodies small. Use 32M if you need uploads.
post_max_size = 8M
upload_max_filesize = 4M
There's one more step. The advisory suggests memory_limit = -1. Set it with php_admin_value in your FPM pool so your app can't change it back:
php_admin_value[memory_limit] = -1
Careful with this one. Without a memory limit, one bad request can eat all the memory on your server. So put a container or cgroup memory limit around PHP as well. Don't use RLIMIT_AS or RLIMIT_DATA for that, because those can trigger the bug themselves.
What's next?
We're waiting for a Docker base image with PHP 8.5.12. As soon as it's out, we'll build a new Flare image and deploy it. Then we'll bring back the dashboard and error reporting, and remove this morning's multipart block.
We'll update this post when that happens.
Continue reading
Introducing: Dark mode for Flare
We heard you, so here it is: a Dark Mode for Flare!
Dries
Automatic breadcrumbs recording and GDPR consent
The latest JavaScript client can record breadcrumbs for you: the clicks, navigations, and HTTP requests a user made before an error, so you can retrace their steps. We also added a consent hook, so nothing is sent to Flare until a visitor accepts your cookie or GDPR banner.
Dries
Subscribe to Backtrace, our quarterly Flare newsletter
No spam, just news & product updates