Step 03 · Verify

Prove the running service changed

A version on disk, a green dashboard and a quiet error log are three different things. Verification is the step where you show which runtime handled a request and which business paths still work.

Reviewed 23 October 2026 Environment Any patched service Official sources

Short answer

Collect evidence at four levels: package, process, traffic, business. A lower level does not prove a higher one.

Package evidence shows what is installed. Process evidence shows what is loaded. Traffic evidence shows what answers requests. Business evidence shows what still works.

Record exceptions as exceptions. “No errors reported” is not a verification result, and a WAF block is not proof that the origin is patched.

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

  • A service has had its PHP runtime updated, replaced or mitigated and needs a completion decision.
  • You need evidence for a manager, an auditor or the next on-call engineer.
  • You suspect that a load balancer, cache or old worker may still serve the previous runtime.

Does not cover

  • It does not search for signs of prior exploitation.
  • It does not certify that the application is free of other vulnerabilities.
  • It does not replace a penetration test or a code review.

What you need before starting

  • The inventory row and the change record for the service.
  • Access to the node, container runtime or hosting console for package and process evidence.
  • A business owner who can define pass or fail for the regression checks.
  • A place to store the evidence that is not a personal desktop.

02Steps

Collect evidence in order. If a level cannot be evidenced, stop and record why; do not infer it from the level below.

  1. System administrator

    Level 1: package or image evidence

    Query the installed package or running image digest on each node. This proves what is present, not what is loaded.

    For a distribution package, compare against the vendor notice, not the upstream version number. For a container, record the digest. For a source build, record the build artefact or commit.

    Store the raw output with the date and node identifier. A screenshot of a terminal without a hostname is weak evidence.

    Package evidence (Debian/Ubuntu)
    dpkg-query -W -f='${Package} ${Version}\n' 'php*' 2>/dev/null | sort
    You should see Each node has a package version or digest that matches the approved target.
    If it fails If a node is missing from the output, it is not verified, even if every other node is.
  2. Platform engineer

    Level 2: running process evidence

    Show that the master and workers started after the installation. A worker that started last week cannot have loaded a binary installed today.

    For FPM, inspect the master and worker start times. For Apache mod_php, inspect the Apache process start time and confirm the module is loaded. For containers, inspect the running container's image digest, not the deployment manifest.

    If the service uses a supervisor that restarts failed workers, confirm the supervisor itself was restarted or is using the new binary.

    Process start times (example)
    ps -eo pid,ppid,lstart,cmd | grep '[p]hp-fpm'
    You should see All serving processes started after the change, and the process list shows no pre-change worker.
    If it fails If old workers remain, return to the patch step. Do not mark verification passed while an old process can still take requests.
  3. Platform engineer

    Level 3: traffic evidence

    Show which nodes or replicas receive requests. Remove old nodes from the load balancer only after the new ones are healthy, then confirm the old nodes are no longer in rotation.

    A health check that returns 200 does not report a PHP version. If you need per-request evidence, use a short-lived, access-controlled diagnostic endpoint that returns the PHP version and SAPI, then remove it and record the removal. Do not leave a public phpinfo() page behind.

    Check caches and proxies that can serve a response without reaching PHP. A cached page tells you nothing about the origin runtime.

    You should see Requests are served by the patched nodes, and any diagnostic used to prove it has been removed.
    If it fails If you cannot separate old and new traffic, use a drain period and record the uncertainty. Do not claim full coverage from a sample.
  4. Business or application owner

    Level 4: business regression

    Run the regression list defined before the change. Include authentication, the primary transaction, uploads, outbound email or queue delivery, scheduled work and the administrative path.

    Define pass and fail before testing. A check that is “looks fine” cannot be audited and cannot be repeated by the next person.

    Record failures as open test bugs with an owner and a target date. Do not fold them into the fix count, and do not let a zero test-bug count stand in for “no vulnerability”.

    You should see Each business check has a result, and every failure has an owner and a date.
    If it fails If the business owner is unavailable, record verification as pending. Do not let the technical team sign off on behalf of the business.
  5. Response lead

    Record the evidence and make the completion decision

    Put the four evidence levels, the exceptions and the decision in one record. The workbook records counts and verification state; the handover template records the narrative and the evidence location.

    Choose one state: not started, in progress, passed, or blocked. “Passed” means the evidence exists, not that the change window closed.

    If any node is unverified, the service is not fully verified. State the scope explicitly: “three of four nodes verified” is a useful answer; “patched” is not.

    You should see A completion state that matches the evidence, with gaps named.
    If it fails If the record cannot be found later, it will be treated as absent. Store it with the service record, not only in a chat thread.

03What usually goes wrong

Checking one node and calling it verified

A load balancer can keep sending traffic to the node you did not check. Verification is per node or per replica.

Using a cached page as traffic evidence

A CDN or page cache can answer without reaching PHP. Check the origin path, not just the public URL.

Treating silence as success

No error log entries may mean the attack failed, the logging is broken, or nobody looked. It is not evidence of a patched runtime.

Public `phpinfo()` left behind

A diagnostic page can expose paths, modules and configuration. Use an access-controlled page and remove it after the check.

04Questions that change the decision

How long should we wait before declaring success?

There is no fixed waiting period that substitutes for evidence. Confirm the running process, the traffic path and the business checks. If you need an observation window, define what you are observing and what would change the decision.

Does a WAF block count as verification?

No. A WAF event can show that a request matched a rule. It cannot show which PHP binary served the origin request, and Cloudflare explicitly says the WAF does not replace the PHP fix.

What if only staging is patched?

Then only staging is verified. Production remains unverified and should be reported that way. Do not average the environments into a single percentage.

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 PHP 8 ChangeLog (8.5.12, 8.4.27, 8.3.36, 8.2.35) Published 2026-10-22 2026-10-23
PHP Group PHP-FPM configuration directives Published date not stated 2026-10-23
Cloudflare PHP vulnerabilities: WAF protection and what customers should do Published 2026-10-21 2026-10-23

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