October 26, 2026
PHP Runtime Truth Check
One page. Three answers to “which PHP are we running?”, and only one of them matters.
By Daniel Akinbade
2 min read
Prepared by Daniel Adekunle Akinbade, Technical Founder @Ayib and AyibFraudGuard. Context: PHP2Shell (CVE-2026–109618 and CVE-2026–109619), patched 21 October 2026. Re-check the official PHP advisory before acting, this story is still moving.
1. The three answers
Source
What it tells you
Trust it for patching?
composer.json
The version you hoped to run (a constraint)
No
php -v
The PHP CLI binary your shell finds first
No
The live worker
The process actually serving web traffic (FPM, mod_php or a container)
Yes
CLI on one version and the web worker on another is common. Verify the worker.
2. Target versions
Per public reporting, fixed releases are PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35. PHP 8.1 and older have no upstream fix in those releases, so rely on your distro or vendor backport, or isolate the service. Confirm against php.net and your vendor advisory.
3. Find the live runtime
Run these on each host. Read-only, safe on prod.
which -a php; php -v # CLI only
php-fpm -v 2>/dev/null || ls /usr/sbin/php-fpm* # FPM binary (name varies by distro)
apachectl -M 2>/dev/null | grep -i php # mod_php present?
docker ps --format '{{.Names}} {{.Image}}' # containers: check the running image, not the tag you think you pulled
docker exec <container> php -vwhich -a php; php -v # CLI only
php-fpm -v 2>/dev/null || ls /usr/sbin/php-fpm* # FPM binary (name varies by distro)
apachectl -M 2>/dev/null | grep -i php # mod_php present?
docker ps --format '{{.Names}} {{.Image}}' # containers: check the running image, not the tag you think you pulled
docker exec <container> php -vDid the running process pick up the patch? A patched package on disk does not patch a running process.
ls -l /proc/$(pgrep -o php-fpm)/exe # "(deleted)" means the process still runs the old binary
ps -o pid,lstart,cmd -C php-fpm # compare start time to your patch timels -l /proc/$(pgrep -o php-fpm)/exe # "(deleted)" means the process still runs the old binary
ps -o pid,lstart,cmd -C php-fpm # compare start time to your patch timeIf you must confirm via phpinfo: keep it on an internal route only, behind auth or an allowlist, and delete it straight after. A phpinfo page left exposed is a vulnerability of its own.
4. The restart gap
- Patch the package or image.
- Restart or reload FPM, or restart Apache if you use mod_php, per your distro's guidance. This affects prod.
- On payment-adjacent paths: drain traffic first, let in-flight requests finish, and confirm idempotency keys are in place so a restart cannot create duplicate or orphaned transactions.
- Re-run the /proc check above. Done means verified, not installed.
5. Secrets to rotate
Assume anything readable by a PHP worker could have been exposed in memory. Rotate highest blast radius first, and tell partners before you touch live integrations:
- Payment gateway and other API keys
- Database credentials
- Webhook signing secrets
- Session and application keys (Laravel APP_KEY rotation invalidates sessions and encrypted data, so plan it)
- Cloud, SMTP and OAuth client secrets
No confirmed breach has been publicly reported as of this writing. Rotation is prudent hygiene, not an admission of compromise.
6. Watch for a week
- Unusual requests to PHP endpoints and new or modified files in web roots
- Unexpected outbound connections from web workers
- Odd transaction patterns around credential use, such as account takeovers or "I did not send this" complaints
7. Evidence log (what leadership will ask for)
Host or service
Runtime (FPM, mod_php, container)
Verified live version
Patched at
Restarted at
Secrets rotated
Owner
8. Do not
- Treat a WAF rule as the fix. It buys time, it does not replace the patch.
- Scan or test systems you do not own or have written permission to test.
- Leave phpinfo reachable from the internet.
Questions or a better way to do this on your stack? Reply in the comments.