An urgent PHP security alert arrived on October 21, 2026. Working with Codex, I checked which of the sites I maintain were affected, then authorized the repairs for this website, Dayton Hash, its staging environment, and the Miami Valley Orienteering Club. Those four website environments turned into five places to fix when I followed the administrative control panel to its separate copy of PHP.

PHP is software on the server that processes requests and runs website code. WordPress depends on it, and so does the backend behind Dayton Hash’s browser interface. A site can need a PHP security update without needing a change to the pages its visitors see.

The PHP team’s announcement described two critical vulnerabilities, CVE-2026-109618 and CVE-2026-109619, that could allow unauthenticated remote code execution. That’s a compact way to say something unpleasant: under the right conditions, someone could send web requests that make the server execute the attacker’s instructions without first signing into the website.

How a request becomes an attack

CVE-2026-109618 concerns what happens when PHP runs out of working memory. A carefully constructed request could exhaust its memory allowance while PHP was still preparing internal data. PHP could then abandon that work and, during cleanup, treat the partly prepared data as valid. The danger goes beyond a crashed page: the resulting memory corruption can let the attacker redirect execution. The demonstrated Apache attack could happen before the website’s own code ran, so an application’s login check wouldn’t yet have had a chance to help.

CVE-2026-109619 concerns what survives between requests. A server worker commonly handles one request after another. An interrupted operation could leave behind directions to temporary data that had already been discarded. An early operation in a later request could follow those outdated directions. With the necessary conditions and carefully arranged requests, that could also let the attacker redirect execution. The details vary with the way PHP is run, the configuration and the application. These are separate vulnerabilities; an attack doesn’t have to use both.

Remote code execution also doesn’t automatically mean unrestricted control of the entire machine. The attacker initially gets the access available to the affected process, which can still be plenty. Depending on those permissions, possible consequences include reading private files or database connection details, changing site content or records, planting malicious files, or taking the service offline. A compromised hosting panel could also put the sites it is allowed to manage at risk. For visitors, that could mean stolen information, altered links or unavailable services. Those are conditional implications of executing code with the web service’s permissions, not findings that those things happened on our sites.

Finding the PHP that needed fixing

The first job was to establish which PHP was actually answering requests. A version number printed in a terminal can belong to a different installation from the one serving the website. MVOC supplied a useful example: its website used PHP 8.2, while its Hestia administration panel used a separately bundled PHP 8.5 runtime. Updating one wouldn’t repair the other.

Our investigation and subsequent request checks accounted for these five environments:

EnvironmentBeforeAfter
jhunterj.comPHP 8.4.24PHP 8.4.27
Dayton Hash productionPHP 8.4.24PHP 8.4.27
Dayton Hash stagingPHP 8.4.24PHP 8.4.27
MVOC websitePHP 8.2.33PHP 8.2.35
MVOC administrative panelPHP 8.5.9PHP 8.5.12

My site and the two Dayton environments run in containers, packaged environments holding the software each service needs. I built replacements that changed the PHP engine while preserving the existing application files, settings and extensions.

MVOC’s website needed updated PHP 8.2 packages instead. I tested the replacement in a separate private PHP process before installation, then checked the workers actually serving the site after the restart. The administrative panel required another approach. Hestia’s package repository still offered the older PHP runtime, but its official source and documented build process provided a path to the fixed version. I built only its PHP package in an isolated local Linux environment matching the server.

This was a package built from official Hestia source, not a patched binary already published in its package repository. I retained the previous package and configuration for recovery, installed the tested replacement, and verified that the running panel process and repeated requests used PHP 8.5.12.

Making the repair survive the next update

Getting the new version running was one part of the work. I also checked that the sites still behaved as expected and preserved their configuration and application files. For Dayton and this site, I rehearsed database restores in isolated environments. Codex used parallel reviewers for site verification; I approved the live changes and later reviewed and merged the follow-up pull requests.

Those pull requests put the PHP fix into the Dayton API’s image recipe and documented how to maintain MVOC’s website and administrative runtimes separately. Otherwise, a later rebuild could quietly put an old PHP engine back. The updated source image passed local build and web-request checks; a future deployment still has to pass its normal release checks.

I then removed temporary test files, unused test resources and merged branches, while keeping the backups and recovery materials. An old package retained for emergency recovery remains vulnerable; restoring it would mean resuming the security repair, not declaring the problem solved.

Looking for signs of a break-in

After the repairs, I asked Codex to investigate breaches associated with the two vulnerabilities. That broadened the work to include MVOC’s separate staging copy, which uses the website’s PHP service, as well as the five repaired environments above.

Parallel reviewers examined request and error logs, website files, and host accounts and scheduled jobs. They used file comparisons and read-only database queries without starting WordPress or executing suspicious files. Logs were copied into a private evidence directory and checked with hashes so later analysis could be tied back to the captured material.

The result was: no confirmed evidence of compromise, but some PHP logs began when the replacement containers started. Older process memory was already gone, some access history was missing, and the investigation had no complete record of commands executed or data sent out. Matching today’s files cannot establish that nobody briefly read a secret or made a change and removed it.

Preserve the evidence before changing the scene

The sequence could have been better. My first request was to identify affected sites and repair them; forensics came later. I should have included a brief evidence-preservation step before the restarts and container replacements. That would have retained more of what could be examined later.

For these non-critical sites, I accept brief unannounced downtime while protecting them during an investigation and update. I’d rather have the affected site temporarily unavailable than leave it exposed while evidence is collected. Where practical, restricting public access can leave the PHP workers alive long enough to capture useful information before restarting them. If immediate containment requires stopping them, the record should say which evidence that sacrificed. A full forensic image can take longer; urgent protection shouldn’t wait silently for an open-ended collection.

I’ve retained that availability preference and the preservation workflow in the project’s agent instructions. The next response should identify the website, staging and administrative runtimes, resolve their real log destinations, preserve what is readily available, and distinguish confirmed compromise from suspicious findings and missing coverage. Original evidence and recovery materials stay through review rather than disappearing in the cleanup.

The configuration work is now in the projects’ backlog task lists. It includes logs that survive container replacement, protected copies away from the server, checks that logging still works after deployment, and a request identifier that connects a visitor’s request with the resulting application records. The planned improvements also cover accurate environment maps, independently retained release baselines, and records that attribute administrative changes to an operator.

More logging needs limits. I need enough information to connect an event to its cause, with bounded storage and controlled access; passwords, session cookies and unrestricted request contents don’t belong in a new collection simply because they might someday be useful. OWASP’s logging guidance is a useful starting point for deciding what to record and what to leave out.

Before the next urgent update, ask which running copies need fixing, whether the next rebuild will preserve the fix, and what evidence will remain after the restart.

—jhunterj

Join the conversation

Your email address will not be published. Required fields are marked *