Step 01 · Assess

Find every PHP runtime that serves a request

Most exposure lives in a runtime nobody remembered: an old staging host, a preview domain, a second FPM pool, a container built two years ago. Start with what answers HTTP, then work back to the binary.

Reviewed 23 October 2026 Environment Any web estate Official sources

Short answer

List services by what serves a request, not by what is in the server inventory. DNS, load balancers, CDN origins and TLS certificates find more than a CMDB usually does.

For each service, record the web SAPI, the package source, the exact version or image digest, and one accountable owner.

php -v reports the CLI binary. It does not prove which binary a web worker is running, and it cannot tell you whether the worker was restarted.

On this page
  1. Does this apply?
  2. Steps
  3. What goes wrong
  4. Decision questions
  5. Next
  6. Sources

01Does this apply to you?

Applies when

  • You run or contract any PHP that answers HTTP requests: PHP-FPM, Apache mod_php, php-cgi, FrankenPHP or LiteSpeed.
  • You have more than one environment, host, container, domain or team.
  • You are not certain that the version in a control panel describes the worker that serves traffic.

Does not cover

  • This page does not scan for exploitation, inspect logs for compromise, or prove that a system is safe.
  • It does not patch anything. Patching is the next step.
  • It does not cover static sites, but it does cover their preview and build environments if those run PHP.

What you need before starting

  • Read access to DNS zones, load balancer or reverse proxy configuration, and CDN origin settings.
  • Access to each host's package manager, container runtime or hosting control panel.
  • A named person who can say what each service is and who pays for it.
  • The workbook open, or a spreadsheet with the same columns.

02Steps

Work from the outside in. Each step produces a record you can defend later; if a step cannot be completed, write down the gap rather than filling it with an assumption.

  1. Whoever owns DNS and routing

    Start from every name that answers HTTP

    Pull the hostnames from DNS zones, load balancer listeners, reverse proxy virtual hosts, CDN custom domains and the subject alternative names on your TLS certificates. Include redirects, parked domains and names that only resolve internally.

    Map each name to the service behind it. A name that returns a redirect still has an origin, and that origin may be an old stack nobody has opened this year.

    Mark names you cannot explain. An unexplained name is a finding, not a gap to hide.

    You should see A list of hostnames, each with a service name and the person who can explain it.
    If it fails If no inventory exists, start with the certificate transparency logs and DNS zone exports for your domains. Record the method and the date, because the list will be incomplete.
  2. Platform engineer

    Identify the SAPI for each service

    The advisory treats SAPIs differently. Apache mod_php was demonstrated exploitable before application code runs. FPM exits a child when request startup fails, but source analysis still indicates exposure after normal startup. FrankenPHP is described as likely susceptible; LSAPI is a conditional candidate.

    Identify what is actually in front of PHP: an FPM pool behind nginx, mod_proxy_fcgi behind Apache, mod_php inside Apache, FrankenPHP, or a LiteSpeed worker. Do not infer it from the application framework.

    A read-only process check is usually enough to start. Confirm the result against the server configuration.

    Read-only process check (Linux)
    ps -eo pid,ppid,lstart,cmd | grep -E 'php-fpm|httpd|apache2|frankenphp|litespeed' | grep -v grep
    You should see Each service is labelled with a SAPI, and the label is supported by configuration or a process listing.
    If it fails If you cannot establish the SAPI, treat the service as unverified and ask the platform owner. Do not assume FPM because the application documentation mentions it.
  3. Platform engineer

    Prove the web runtime version, not the CLI version

    On a host, php -v executes the CLI binary. A server can have a patched CLI and an unpatched FPM binary, or the reverse. Check the binary that the service starts, then check that the running process was started from it.

    For FPM, the pool configuration names the binary or the system service does. Confirm the path and version of that binary. For Apache mod_php, the PHP module is loaded into the Apache process, so the Apache restart matters, not a separate FPM service.

    Do not publish phpinfo() to answer this question. A temporary page readable only from localhost or behind authentication is acceptable if you remove it afterwards and record that you did.

    FPM binary and process start time (example)
    command -v php-fpm && php-fpm -v && ps -eo pid,lstart,cmd | grep '[p]hp-fpm'
    You should see The record shows the binary path, its reported version, and the start time of the running master and workers.
    If it fails If the binary path is a versioned path such as /usr/sbin/php-fpm8.3, record the path as well as the version. Package upgrades can leave an old unit pointing at the old path.
  4. System administrator

    Record the package source and exact version

    The fix has to come from the source you actually run. A distribution backport can carry a version string that looks older than the upstream fixed version while containing the patch. Comparing bare version numbers across sources produces false conclusions.

    For Debian or Ubuntu, query the installed package and its version. For RHEL-family systems, query the RPM. For containers, record the image digest, not only the tag, because a tag can be moved.

    If PHP is built from source, record the build commit or the patch set, not only the PHP_VERSION string.

    Debian/Ubuntu package versions
    dpkg-query -W -f='${Package} ${Version}\n' 'php*' 2>/dev/null | sort
    You should see Every service has a package name and version, or an image digest, or a source build reference.
    If it fails If the package source is unknown, the service cannot be verified later. Escalate it as an ownership problem before patching.
  5. Service owner

    Add the copies people forget

    Check staging and preview deployments, blue-green or canary nodes still attached to a load balancer, administrative panels on separate hosts, scheduled jobs that run a separate PHP container, and backup restores that are reachable from a network.

    Separate HTTP workers from CLI workers in the inventory. The published advisories address web request handling; CLI is not the same exposure path. It still runs the same code and may hold the same credentials, so do not leave it unowned.

    If a system is genuinely out of scope, write down why. “Probably unused” is not a scope decision.

    You should see The inventory includes the forgotten copies, or states why each is excluded.
    If it fails When a copy has no owner, record the gap and the date by which it will be resolved. Do not silence it by deleting the row.
  6. Response lead

    Put one accountable owner on every row

    A team name is not an owner. Record a role or an alias that can answer a question about the system, and keep personal data out of the workbook.

    Open the workbook, add one row per business line or system, and record how many distinct fix items are required. Do not count functions, hosts and packages as if they were the same unit.

    Record the unknown rows explicitly. They will drive the questions in the management update.

    You should see Every row has an owner and a fix count, including rows where the answer is still unknown.
    If it fails If nobody will accept ownership, report that as a governance issue. A patch programme without owners stalls at the first legacy host.

03What usually goes wrong

Trusting `php -v`

The CLI and the web worker can be different binaries. Use the service's own binary and confirm the process start time.

Assuming one PHP version per host

Multiple FPM pools and versioned package paths can coexist. A host is not a runtime; a pool or container is.

Missing the origin behind a CDN

A CDN hostname tells you nothing about the origin. Record the origin server or service separately, including any direct-to-origin path that bypasses the CDN.

Recording a container tag as a version

Tags move. Record the digest that is running, and keep the tag as a label only.

04Questions that change the decision

Is CLI PHP affected by these CVEs?

The advisories describe web request handling and list web SAPIs. CLI is not addressed as an attack path. That does not make CLI irrelevant: it runs the same application code and often holds the same credentials. Inventory it, but do not claim a web exposure finding from a CLI version alone.

Can I use an online scanner instead?

A scanner can add evidence, but it cannot tell you who owns a service, whether a distribution backport contains the fix, or whether old workers are still running. The inventory is the part you cannot outsource.

How many rows should the workbook have?

One row per business line or system that has its own owner and fix count. Splitting a single system into many rows to make progress look better is a reporting choice, not a technical one; keep the definition consistent.

05Where to go next

06Sources and revision

Every operational claim on this page was checked against the documents below on 23 October 2026. This page was last substantively changed on 23 October 2026.

Primary sources used for this page
PublisherDocumentChecked
PHP Group Security advisory: Critical remote code execution vulnerabilities, update now Published 2026-10-21 2026-10-24
PHP Security Team / GitHub GHSA-w8hw-w9fx-j79w: RCE via OOM corruption Published 2026-10-21 2026-10-23
PHP Security Team / GitHub GHSA-6wmf-4rv5-p3rp: RCE via stale global state Published 2026-10-21 2026-10-23
PHP Group Supported Versions Published date not stated 2026-10-24
PHP Group PHP-FPM configuration directives Published date not stated 2026-10-23

See the full revision log for what changed on this site.