The PHP-FPM status page is a version disclosure you can turn off
Published · updated
Most sites work hard to hide their PHP build, then leave a page open that publishes it — along with the pool's process model, limits and the URIs currently being served. It takes one line in a pool config to close.
What the page shows
When pm.status_path is configured in a pool and the web server passes that location to FPM, a request to it returns a live status document. In its text form:
pool: www process manager: dynamic start time: 21/Oct/2026:13:02:11 +0000 start since: 18392 accepted conn: 2841 listen queue: 0 max listen queue: 12 listen queue len: 511 idle processes: 3 active processes: 1 max active processes: 8 max children reached: 0
With the full view the page also lists each worker and the request it is handling — the URI, the script path, the method. That is the part that turns a curiosity into a reconnaissance gift: an attacker learns your endpoint names, which ones are slow, whether an admin path exists, and how many workers they can occupy.
The start time and build string in some configurations also pin down the PHP build and the last restart — useful when someone is checking whether a patch actually landed.
Find out whether yours is public
Try the usual paths, with and without the query that asks for the full view:
for p in status fpm-status php-fpm-status status.php ping; do
printf '%-18s %s\n' "$p" "$(curl -sk -o /dev/null -w '%{http_code}' https://example.com/$p)"
done
curl -sk 'https://example.com/status?html' | head -40
A 200 with the words pool: and process manager: is the status page. A 200 with your normal site layout is a catch-all route, not a status page — check the body, not the code. Ours reports this leak as a separate finding, exactly because it survives the removal of X-Powered-By.
Close it properly
- Remove the path if you do not use it. Comment out
pm.status_path = /statusin the pool file (/etc/php/8.3/fpm/pool.d/www.conf) and reload FPM. This is the correct fix for most sites — the page exists for local diagnostics, not for visitors. - If you need it, restrict it at the web server. nginx:
location = /status { allow 127.0.0.1; allow 10.0.0.0/8; deny all; access_log off; fastcgi_pass unix:/run/php/php8.3-fpm.sock; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; }. Apache: wrap the location inRequire ip 127.0.0.1. - Better: put it on its own socket.
pm.status_listen = /run/php/php8.3-fpm-status.sock— then only a local monitoring script can reach it and no web path is needed at all. - Verify from outside. The path should return 403 or 404, and the response body must not contain
process manager.
Why it matters this month
Two unauthenticated RCEs in PHP core were fixed on 21 October 2026 (CVE-2026-109618, CVE-2026-109619). The second needs two related requests to reach the same worker. A status page that shows the process count, the listen queue and the request assignment is a map for arranging exactly that — and, at the same time, it is how many sites accidentally publish the build number an attacker needs to decide whether the patch landed.
Closing it is not the fix. It removes a leak and one piece of convenience from someone else's planning. The patch is the fix.
Questions
Is an exposed FPM status page a vulnerability?
It is an information disclosure, not code execution. It becomes serious in combination with a known bug in the build it reveals, and it is one of the few leaks that also exposes your request structure.
I get 404 on /status — am I safe?
You are not exposed through that path. Check other usual paths and the ?html/?full variants before concluding; some setups map the status page to a different location.
Will closing it break my monitoring?
Only if your monitoring reads it over HTTP. Move the check to the separate status socket, or to a local script, and keep the outside path closed.
Does the page show the PHP version?
The full output and the pool section do in most builds. Even where it does not, the process list is enough to plan an attack on the two-request variant of CVE-2026-109619.