
Loading

Loading
We use strictly necessary cookies to run this site, and analytics cookies to understand how it's used. See our Privacy Policy for details.

A security patch is easy to approve.
Summary
Finding every PHP runtime hidden in an old container, appliance, control panel, or forgotten staging server is the harder part. That problem became urgent after PHP disclosed two critical remote code execution flaws, CVE-2026-109618 and CVE-2026-109619, known together as PHP2Shell. The PHP project released fixed versions on October 21, 2026.
Its advisory says any PHP installation serving web requests could be at risk, including PHP-FPM, Apache mod_php, php-cgi, FrankenPHP, and LiteSpeed. The project's rating of the risk is highest for mod_php, where a demonstrated request could reach the flaw before application code ran. (PHP security advisory) The discovery story needs careful attribution. Calif Research says it found the first PHP2Shell bugs during its audit.
OpenAI's account says GPT-5.6 Sol helped Calif identify the critical flaw, while Wiz describes a separate, later audit that used both Gemini 4 Argon and GPT-5.6 Sol. Wiz says Argon made a significant contribution to its discovery. These accounts support a narrower claim: AI-assisted research helped expose these issues.
They do not mean an AI autonomously found every flaw or built the full exploit chain. (Calif Research's account, OpenAI's account, Wiz's account) For operators, the urgent question is practical: which PHP runtimes serve real traffic, and how do you prove they were updated and restarted? Here is a cautious inventory and patch-verification workflow. It does not exploit anything.
It helps you find the runtime that a package list or a single php -v command can miss. Start with the exact fixed versions The PHP project's October 21 security release lists these fixed upstream versions: PHP 8.5.12 PHP 8.4.27 PHP 8.3.36 PHP 8.2.35 Linux distributions and long-term-support vendors may backport security fixes without changing the upstream version number in the same way. PHP says to check with the vendor for updated packages.
PHP 8.1 and older no longer receive updates from the PHP project, though a distribution or vendor may provide its own backport. Do not declare an old-looking version vulnerable or fixed based only on the version string. Confirm the package's vendor advisory or build provenance. (PHP advisory) The report from the Dutch National Cyber Security Centre is useful here because it tracks both PHP itself and downstream software that may bundle PHP.
Its inventory listed 948 products on November 4, with 215 marked vulnerable and 185 fixed at that snapshot. Those counts change as maintainers update the list, so treat them as a dated inventory, not a current universal total. (NCSC-NL PHP2Shell tracker) Why php -v is not a complete audit A shell command named php usually reports the command-line interpreter selected by your current PATH. A website may instead use PHP-FPM behind Nginx, an Apache module, a container image, a hosting control panel, or PHP embedded inside a third-party appliance.
Those may be different builds. A machine can have multiple PHP versions installed at once. Updating the CLI package does not prove that the process serving requests was updated, and replacing a package does not prove that old workers have exited.
Think of this as an inventory problem with three layers: Hosts: virtual machines, physical servers, cloud instances, and staging systems. Runtimes: package installs, custom builds, containers, and bundled copies. Traffic paths: the service or appliance that actually accepts web requests.
A clean result in one layer does not clear the other two. The NCSC-NL guidance explicitly recommends identifying PHP-based applications and checking third-party images, appliances, and embedded runtimes separately. (NCSC-NL operational guidance) Step 1: List every place PHP could run Start with your asset inventory, cloud console, deployment configuration, and hosting panel. Search for PHP-related service names and image tags in infrastructure code.
Include production, staging, build workers that serve previews, and appliances managed by another team. On each Linux host you administer, these read-only commands provide useful clues: command -v php || true php -v 2>/dev/null || true php --ini 2>/dev/null || true ps -eo pid,comm,args | grep -E '[p]hp-fpm|[p]hp-cgi|[a]pache2|[h]ttpd|[l]itespeed' systemctl --type=service --state=running | grep -Ei 'php|apache|httpd|nginx|litespeed' They are discovery aids, not a complete scanner. Process names vary by operating system and package.
A reverse proxy such as Nginx may pass requests to PHP-FPM, so seeing Nginx alone tells you little about the PHP version. Likewise, a process list can show a service without identifying the image or package that supplied its binary. For Debian- or Ubuntu-based hosts, inspect installed packages as a second view: dpkg-query -W -f='${Package} ${Version}\n' 'php*' 2>/dev/null For RPM-based hosts, check the package database with the package tool used by that system.
Do not assume the package name is identical across distributions or third-party repositories. If the system uses a hosting panel, consult its supported runtime list too. Panel-managed PHP builds can live outside the operating system's standard package paths.
The point is to gather evidence from multiple places, not to trust one command. Record the hostname, application, runtime source, serving mode, reported version, owner, and next action. If you cannot identify the runtime owner, mark the asset as unresolved rather than treating it as safe.
Step 2: Check containers and bundled products A host can be patched while a container continues to run an older PHP image. List the containers that are actually running, then trace each one to its image and deployment definition: docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Status}}' This only reports containers visible to the Docker daemon you queried. Repeat for each cluster, account, and environment, and use your orchestrator's deployment inventory for Kubernetes or other platforms.
For every PHP image, identify its base image and rebuild from an image containing a vendor-fixed runtime. A tag such as latest is not proof that the deployed image changed; compare immutable image digests or your registry's build metadata. Also check products that embed PHP rather than exposing a PHP package directly.
The NCSC-NL tracker names downstream software and points to supplier advisories. A product may require a vendor firmware or appliance update even when you cannot run php -v on it. For hosted services, ask the provider whether the relevant fleet or service component has been patched, and request the affected product version or rollout status. (NCSC-NL product inventory) This is where a version-only policy often fails.
“The server is on PHP 8.4” leaves unanswered which build, which host, and which process. A more useful record says: “The public web tier runs the vendor package with the security fix; the FPM service was restarted; the running process now reports the expected build.” Step 3: Patch through the owner of the runtime For a standard distribution package, use that distribution's security update process and verify its advisory. For a container, rebuild and redeploy the image.
For a managed platform, apply the provider's update process. For a custom build, use the relevant PHP release and deployment process, then verify the binary and all service workers. Do not copy a package command from a different operating system or panel.
A command that appears to succeed may update the wrong PHP stream or leave the serving service untouched. The official PHP page says Linux distributions and LTS vendors received patches in advance, which is why the vendor's package status matters. (PHP security advisory) After deployment, restart or reload the relevant PHP and web-server processes using the service manager and procedure for your platform. Then check that the old workers are gone.
The NCSC-NL guidance also calls out restarting workers when mitigation steps are used. A replaced executable on disk is not enough if a long-running process still has the old code mapped in memory. (NCSC-NL operational guidance) Step 4: Verify the serving process, not just the package Use a platform-specific health check that identifies the PHP version from the web-serving path. For example, an application can expose a temporary, access-controlled diagnostic endpoint that returns only the runtime version and SAPI.
Remove it immediately after checking. Do not publish a public phpinfo() page: it can disclose configuration and environment details unrelated to this patch. For PHP-FPM, verify the package or image used by the pool, confirm the service restarted, and inspect the running process list.
For Apache mod_php, check the Apache module and the PHP build loaded by Apache. For a containerized service, verify the deployed image digest as well as the runtime inside the running container. For appliances and managed services, use the vendor's version report or written confirmation.
Keep a small evidence record for each asset: The package, image digest, appliance build, or vendor update that contains the fix. The service or deployment that was restarted or rolled out. A post-update check showing the serving runtime is the expected build.
Any exception, owner, and deadline if an asset could not be updated. The goal is not paperwork for its own sake. This record helps prevent an old canary, preview environment, or secondary node from being forgotten after the main application passes its health check.
If patching is delayed PHP's project has described temporary mitigations, including disabling session upload progress and reviewing settings such as memory_limit, post_max_size, and PHP 8.5's fatal_error_backtraces. The NCSC-NL guidance explicitly says these steps are not complete fixes. PHP's October 23 informational advisory also recommends session.upload_progress.enabled=0 until the next regular bug-fix release for an unlikely additional RCE vector, CVE-2026-115560.
It notes that the risk depends on an unusual combination of session-handler configuration and application behavior. (PHP advisory and update, NCSC-NL guidance) Treat these as temporary risk reduction, not a substitute for the vendor-fixed runtime. Do not blindly change memory or request-size limits on a busy service without checking application requirements. Test configuration changes, document them, and schedule the actual patch.
A separate operational point matters: Singapore's Cyber Security Agency published an alert on November 3, 2026, describing active exploitation against selected network and security products, including reports of attackers chaining PHP2Shell with a separate Linux kernel flaw. That is not evidence that every PHP installation has been compromised. It is a reason to check product-specific vendor guidance and review logs for systems that could have been exposed. (Singapore CSA alert) What AI changes, and what it does not The public accounts describe more than one audit, with different researchers and different models involved.
Calif says its audit found the first PHP2Shell bugs. OpenAI says GPT-5.6 Sol helped identify the critical flaw. Wiz later reports a separate investigation that used Gemini 4 Argon and GPT-5.6 Sol, with Argon making a significant contribution.
These are the organizations' own accounts of their research, not independent measurements of how much work a model did. (Calif Research, OpenAI, Wiz) The useful lesson is not “AI automatically hacks old software.” The evidence here is narrower: capable models contributed to researchers' audits of a mature codebase, and those audits found serious flaws. Years of deployed versions and rarely audited products still need human owners who can inventory, update, restart, and verify them. The defenders' work is less glamorous: know what is running, know who owns it, update the right artifact, restart the right process, and verify the result.
That is exactly the kind of work that becomes more important when vulnerability discovery speeds up. A short checklist to keep Inventory: include hosts, containers, staging, control-panel runtimes, and appliances. Identify the serving mode: CLI version alone does not identify PHP-FPM, mod_php, or a bundled runtime.
Use vendor evidence: confirm upstream fixed versions or vendor backports. Deploy and restart: update the artifact that serves requests, then ensure old workers exit. Verify: check the live runtime or vendor build, not only the package manager's success message.
Track exceptions: assign an owner and deadline to anything still unknown or unpatched. Review exposure: follow product-specific advisories and investigate suspicious activity where appropriate. The hard part of this incident is not typing an update command.
It is finding the copy of PHP nobody remembers deploying. A reliable inventory turns that into a finite list instead of a guess. I write about software engineering, security, and AI.
Subscribe if you want the next practical breakdown. Have you found a PHP runtime in a place your normal inventory missed? What check exposed it?
Save this checklist for your next runtime patch cycle.
KazaSec's take
Incidents like this rarely start with the headline event itself, they usually trace back to an exposed remote-access endpoint, an unpatched perimeter system, or a credential phished weeks earlier. The organizations that recover fastest are the ones that tested their defenses and their incident response plan before they needed them.
Coverage details
We've archived 869 other articles touching the same topic (security, devops, ai) , see the full security news archive.
Related security advisories
Relevant from KazaSec
More coverage on this topic
We help organizations find and fix the gaps before they make headlines.