Safeguard
Supply Chain Security•

After PHP2Shell: how to check if your server was already compromised

Patched PHP2Shell? Check web roots, processes, cron, accounts and outbound traffic, review logs from 20 Oct, rotate secrets, and rebuild if you find signs.

Safeguard Security Team
27 min read

Patching PHP2Shell closes the hole but does not tell you whether anyone got in first. If an internet-facing PHP server ran a vulnerable version, check the web root for new files, look for odd processes, cron jobs, accounts and outbound connections, review logs from 20 October onward, rotate secrets the server held, and rebuild any host that shows signs.

The UK NCSC put it plainly on 21 October: organisations that could not update straight away should assess systems for evidence of compromise and look for "backdoors installed by an attacker" before upgrading or applying mitigations. This post turns that advice, plus what PHP, the CERTs, Huntress, watchTowr and Wiz have published and the older NSA, ASD and CISA web shell guidance, into checks you can run today.

If you need the background on the two flaws first, start with PHP2Shell explained. If you are still patching, find and patch every PHP runtime covers that, and if you took sites offline, governments take websites offline over PHP2Shell covers the decision to bring them back. This post assumes the fix is in and the workers have restarted.

What happened, and why it sets your review window

The dates below decide how far back your log review needs to go. The key point: details were public for most of a day before the fixes shipped, and some sources say exploitation began on release day.

WhenWhatSource
20 Oct, morningClaims of two critical PHP RCE flaws circulate after an early post is taken downHuntress
20 OctPHP posts an advance notice of a critical release for 21 Oct, 14:00 UTCphp.net
21 Oct, 10:00 ETHuntress has not seen in-the-wild exploitation across its partnersHuntress
21 Oct, about 13:30 to 13:45 UTCFixed releases 8.5.12, 8.4.27, 8.3.36 and 8.2.35 go live (CERT-EU says 13:30 UTC; Reuters, via KSL, says about 13:45 GMT)CERT-EU, php.net
21 OctUK NCSC publishes its alert, including the instruction to check for compromiseNCSC
21 OctwatchTowr's FAQ says its honeypots observed exploitationwatchTowr

Sources disagree on exploitation. watchTowr reports honeypot hits on 21 October; Huntress, earlier that day, had seen none, and The Hacker News reported the Dutch NCSC had not seen abuse. No source we read published confirmed indicators of compromise, so the checks below look for behaviour rather than hashes or IP addresses.

Your review window is not "release day only". It runs from at least the morning of 20 October until the moment your workers actually restarted on the patched binary, which may be later than when the package was installed. The flaws themselves are old: Wiz says they affect PHP versions back to 5.4. No source we read reports exploitation before the leak, but nobody can rule it out either, so look as far back as your logs allow for your highest-risk hosts.

Who needs to run these checks

Not every PHP install carries the same risk. PHP's advisories rate Apache mod_php as the highest-risk setup, with conditional paths on PHP-FPM, FrankenPHP and LiteSpeed. Use this to decide where to start.

Your situationPriorityWhy
Internet-facing Apache mod_php, unpatched past the evening of 21 OctCheck first, assume compromise until shown otherwiseHighest-risk SAPI per PHP; public details for over a day
Internet-facing PHP-FPM or LiteSpeed, patched on 21 OctFull checkConditional paths exist; memory disclosure possible
End-of-life PHP (8.1 and older) still onlineFull check, plan a rebuildNo upstream release; backports vary
Vendor appliance or control panel with bundled PHPAsk the vendor, then check what you canNCSC and NCSC-NL both say bundled PHP needs separate tracking
A site you took offline as a precautionFull check before it comes backOffline after the leak does not mean it was untouched before

What the guidance actually says

Some summaries online blend these sources. Here is what each one we fetched actually says about compromise.

SourceWhat it says about compromise
UK NCSC alertAssess for evidence of compromise and backdoors; use an NCSC-assured incident response provider if you lack confidence
NCSC-NL php2shell repoMonitor internet-facing logs and public exploit activity; inventory of products with a PHP dependency; cPanel mitigation script; no compromise checklist yet, and the repo says it "is currently being expanded"
CERT-EU 2026-018Patch now; isolate internet-facing systems if you cannot; no compromise or log guidance
PHP GitHub advisoriesLog patterns tied to the bugs: memory exhaustion, fatal errors, worker crashes, FPM child exits; keep logging on
HuntressAlert on PHP workers spawning shells, interpreters or download tools; isolate, keep logs, look for web shells, new web root files, new cron jobs, tasks and accounts; IOCs pending
watchTowrPreserve logs, configs and suspicious files before changes; look for web shells, unexpected cron jobs, new accounts tied to PHP processes
WizHunt for multipart requests followed by memory errors, repeated HTTP 500s, oversized PHPSESSID cookies, worker churn; host and proxy telemetry beats app logs
The Hacker NewsSame request-level signs; flaws can expose worker memory without code execution

PHP's advisory adds one line every responder should keep in mind: "absence of an error in logs is not proof of safety." Logs may skip some severities, and some failures happen before PHP writes anything.

How a compromise would show up

Two different outcomes leave very different traces.

Code execution. If an attacker ran code through a PHP worker, it ran as that worker's user (often www-data or apache). Typical follow-ups are a web shell in a served directory, a cron job, a new account or SSH key if privileges allow, and downloads of more tools. These leave files, processes and connections you can find.

Memory disclosure. The Hacker News reports, and Wiz repeats, that the flaws can let an attacker read memory from the worker process without running code. That memory may hold passwords, session tokens, API keys and certificates from other users' requests. It leaves almost nothing on disk, which is why this guide includes credential rotation even for servers that pass every file check.

Before you touch anything: preserve evidence

The joint advisory on uncovering malicious activity from CISA and its Five Eyes partners (AA20-245A) lists common mistakes. Three apply here: fixing the system before collecting data, resetting credentials before you know how far an attacker got, and fixing only the symptom. watchTowr says the same for PHP2Shell: preserve logs, configuration snapshots and suspicious files before making changes.

  1. Snapshot first. On a VM or cloud instance, take a disk snapshot before you start deleting or editing. For containers, do not restart the pod yet if you suspect it.
  2. Copy the logs off the host. Web server access and error logs, PHP-FPM logs, the PHP error log, the system journal and auth logs. Rotated and compressed files too.
  3. Record the timeline. When the package was installed, when the workers restarted, when any WAF rule went live.
# Copy logs to a separate machine before anything else
sudo tar czf /tmp/ir-$(hostname)-logs.tgz /var/log/apache2 /var/log/httpd \
  /var/log/nginx /var/log/php* /var/log/auth.log* /var/log/secure* 2>/dev/null
scp /tmp/ir-$(hostname)-logs.tgz analyst@ir-box:/cases/php2shell/

# When did the patched workers actually start?
ps -o pid,lstart,cmd -p "$(pgrep -o php-fpm)"
ps -o pid,lstart,cmd -p "$(pgrep -o -x apache2 || pgrep -o -x httpd)"

The worker start time is the end of your exposure window. A package installed at 14:00 means nothing if FPM kept running the old binary until a reboot two days later.

Step by step: checking a PHP server for compromise

Run these as a lead-generation exercise. None of them proves compromise alone, and none proves a clean host alone. Paths vary by distribution; adjust /var/www, log locations and the web user to match yours.

1. Compare the web root against a known-good copy

The NSA and ASD web shell guidance calls comparison against a known-good version the most effective way to find most web shells. If your app deploys from Git or a build artifact, you already have that copy.

# Known-good comparison, as in the NSA Mitigating-Web-Shells repo
diff -rq /srv/known-good/app/ /var/www/html/

# For a Git-deployed tree, anything untracked or modified is a lead
git -C /var/www/html status --porcelain --ignored

# For Composer projects, compare vendor/ with a fresh install elsewhere
composer install --no-dev --no-scripts --working-dir=/tmp/clean-build
diff -rq /tmp/clean-build/vendor /var/www/html/vendor

Review every difference by hand. Uploaded media, caches and generated files will show up; PHP files that nobody deployed should not.

2. Look for new or out-of-place PHP files

CISA's long-running web shell guidance flags files newer than the last deploy and unexpected files in served directories. Be aware that attackers can change file timestamps, which the NSA guidance calls timestomping, so treat dates as a filter, not proof.

# PHP and config files changed since the leak
find /var/www -type f \( -name '*.php' -o -name '*.phtml' -o -name '*.phar' \
  -o -name '.htaccess' -o -name '.user.ini' \) -newermt '2026-10-20' -ls

# PHP files in places that should only hold uploads or cache
find /var/www -type f -path '*upload*' -name '*.ph*' -ls
find /var/www -type f -path '*cache*' -name '*.ph*' -ls

# Temporary directories the web user can write to
sudo find /tmp /var/tmp /dev/shm -type f -newermt '2026-10-20' -ls

# Directives that load extra code on every request
grep -RniE 'auto_(prepend|append)_file' /etc/php* /var/www 2>/dev/null

The last check matters because a line added to a .user.ini, .htaccess or pool file can make every request load attacker code without any new file appearing in an obvious place.

3. Verify system packages have not been altered

Your package manager can tell you which installed files no longer match what the package shipped.

# Debian and Ubuntu (install debsums first if needed)
sudo debsums -c 2>/dev/null

# RHEL, Alma, Rocky, SUSE: '5' in the third column means the checksum changed
sudo rpm -Va | grep -E '^..5'

Edited config files will show up legitimately. Changed binaries in /usr/bin or /usr/sbin, or changed PHP extension files, should not.

4. Check what the web workers are running

Huntress recommends alerting when php-fpm, php-cgi, httpd or apache2 spawns a shell, an interpreter such as Python or Perl, or a download or network tool such as curl, wget or nc. It also suggests watching for reconnaissance commands run from the web server. For Linux hosts without endpoint tooling, Huntress points to Florian Roth's process-watcher, which can run in observe mode.

# Process tree under the web server and PHP workers
ps -eo pid,ppid,user,lstart,cmd --forest | grep -E -A4 'php-fpm|php-cgi|lsphp|frankenphp|apache2|httpd'

# Anything running as the web user that is not the server itself
ps -u www-data -o pid,ppid,lstart,cmd | grep -vE 'php-fpm|apache2|httpd'

A live check only shows what is running now. If you have auditd, Sysmon for Linux or an EDR, search its history for child processes of the web server across the whole window.

5. Look at outbound connections

A web server mostly answers connections. It usually starts only a few of its own, to a database, a cache, a mail relay or known APIs. Anything else is worth a look. The NSA guidance lists unexpected network flows from web servers as a detection method.

# Current connections owned by web processes
sudo ss -tunp | grep -E 'php|apache2|httpd|lsphp|frankenphp'

# Everything the web user has open on the network
sudo lsof -i -a -u www-data

Again, that is a snapshot. The better evidence is history: egress firewall logs, proxy logs, VPC or NSG flow logs, and DNS query logs for the review window. Look for new destinations, connections on unusual ports, and DNS lookups for domains your app has never used.

6. Hunt for persistence and new access

Huntress and watchTowr both list new cron jobs, scheduled tasks and accounts. CISA's AA20-245A adds systemd units, unexpected SSH keys in authorized_keys, and system accounts that have been given interactive shells.

# Cron for the web user and system-wide
sudo crontab -l -u www-data
ls -la /etc/cron.* /var/spool/cron/ /var/spool/cron/crontabs/ 2>/dev/null

# systemd timers and units changed recently
systemctl list-timers --all --no-pager
sudo find /etc/systemd /usr/lib/systemd /lib/systemd -newermt '2026-10-20' -type f -ls

# Accounts with a login shell, and recently changed SSH keys
awk -F: '$7 !~ /(nologin|false)$/ {print $1, $3, $7}' /etc/passwd
sudo find / -xdev -name authorized_keys -newermt '2026-10-20' -ls 2>/dev/null

# Application-level admins, for example on WordPress (WP-CLI)
wp user list --role=administrator --fields=ID,user_login,user_registered --path=/var/www/html

Do not forget the application layer. A new CMS administrator, a new API token in your app's database, or a changed plugin is a backdoor that survives a server rebuild if you restore the same database.

7. Review the logs for the window

PHP's advisories, Wiz and The Hacker News list the same family of signs: memory exhaustion errors on POST requests, especially multipart uploads; fatal errors and timeouts on public routes; segmentation faults and PHP-FPM children exiting unexpectedly; bursts of HTTP 500 responses; and unusually large PHPSESSID cookies in responses.

# Memory exhaustion and fatal errors (adjust log paths)
zgrep -h 'Allowed memory size' /var/log/php*fpm*.log* /var/log/apache2/error.log* 2>/dev/null | head -50
zgrep -h -E 'PHP Fatal error|Maximum execution time' /var/log/apache2/error.log* 2>/dev/null | head -50

# FPM children dying on a signal, and kernel segfault records
zgrep -h -E 'exited on signal|SIGSEGV' /var/log/php*fpm*.log* 2>/dev/null
journalctl -k --since '2026-10-20' | grep -i segfault

# HTTP 500s per hour from a combined-format access log
awk '$9==500 {split($4,t,":"); print t[1]":"t[2]}' /var/log/apache2/access.log | sort | uniq -c

# Rarely requested URLs that returned 200 (the idea behind NSA's LogCheck script)
awk '$9==200 {sub(/\?.*/,"",$7); print $7}' /var/log/apache2/access.log | sort | uniq -c | sort -n | head -40

Correlate. A memory error alone is common on a busy site. A memory error, followed by a worker crash, followed by requests from the same address to a PHP file that was not in your last deploy, is a story. If your traffic went through a CDN or WAF, pull its logs too; they often keep request details your origin never saw.

8. Containers and orchestrated workloads

Containers make one part easier. If the filesystem is meant to be read-only or rebuilt each deploy, any change is suspicious.

# Files added (A) or changed (C) inside a running container since it started
docker diff <container-id>

Check pod restart counts and termination reasons for the window too, since crash loops line up with the worker instability the advisories describe. Then redeploy from a freshly built image rather than patching a running container in place.

Credential rotation: what to rotate and when

The Hacker News and Wiz both say worker memory can expose passwords, tokens, keys and certificates. Neither publishes a rotation list, so here is ours. Rotate after containment and evidence collection, since AA20-245A warns that early resets can tip off an attacker who still has access.

SecretWhere it usually livesWhat to do
Database passwordswp-config.php, .env, app configNew credentials, least privilege, update app, revoke old
Third-party API keys.env, environment variables, configRotate at the provider; check provider logs for use from unknown IPs
Framework and session secretsLaravel APP_KEY, WordPress salts, Symfony APP_SECRETRotate per your framework's docs; note this can log everyone out or affect encrypted data
User sessionsSession store, cache, databaseInvalidate all active sessions; consider forcing password resets for admins
TLS private keys on the hostWeb server configReissue and revoke if any sign of code execution
Cloud credentialsInstance roles, keys in env or filesRotate static keys; review cloud audit logs for the window
SSH keys and deploy keysauthorized_keys, CI secretsRemove unknown keys; rotate deploy keys the host could read

If you found signs of code execution, widen the list to everything the web user could read, not just what PHP had in memory.

Rebuild or clean?

CISA advises rebuilding from a known-good image, and AA20-245A says to reimage or remove compromised systems. Our view: any real evidence of code execution means rebuild. A cleaned server leaves you guessing about what you missed.

FindingRecommended action
Unknown PHP files, a web shell, or changed auto_prepend_fileRebuild from known-good image; redeploy app from source; rotate all secrets
Web workers spawned shells, interpreters or download toolsRebuild; treat everything the web user could reach as exposed
New accounts, SSH keys, cron jobs or systemd unitsRebuild; check other hosts that share credentials
Changed system binariesRebuild; assume root-level access
Only memory errors or crashes, no file, process or persistence findingsPatch, restart, rotate secrets, keep monitoring
Logs missing for part of the windowTreat as unknown; rebuild internet-facing mod_php hosts
No indicators and full log coverageKeep the host; rotate session secrets; monitor

When you rebuild, use a new image from a trusted source, deploy the application from version control or a signed build artifact, restore only data (not code) from backup, and check the restored database for planted admin users before the new host goes live. If you are not confident doing the investigation in house, the NCSC recommends using an NCSC-assured Cyber Incident Response provider; outside the UK, your national CERT can point you to equivalents.

What would have helped

The hard part of answering "were we hit?" is having the baseline and the logs before the incident.

Practices any team can use

  • Immutable deploys. If every release is a fresh image or a clean checkout, the known-good comparison takes minutes. Servers edited by hand over years cannot be compared with anything.
  • A read-only web root. The web user should not be able to write PHP files where they will be served. Keep uploads in a directory with PHP execution disabled.
  • Process alerts on web servers. The Huntress rule, a web worker spawning a shell or download tool, is cheap to set up and useful well beyond PHP2Shell.
  • Egress control. A web server that can only reach its database, cache and a short allow list of APIs gives an attacker much less to work with, and makes any odd connection obvious.
  • Logs kept off the host for months. Local logs rotate away quickly, often within weeks. AA20-245A recommends keeping log data for at least a year.
  • Secrets that are cheap to rotate. Short-lived credentials, a secrets manager, and a tested rotation runbook turn "rotate everything" from a weekend into an hour.

Where Safeguard fits

Safeguard would not have prevented PHP2Shell, and it is not a forensics tool. It does not hunt for web shells on running hosts, read server logs, watch process trees or tell you whether a box was compromised. Where it helps is scoping and the rebuild:

  • Which builds carry the vulnerable PHP. safeguard scan --image <name> builds an SBOM of a container image, including OS packages such as PHP, and matches components against vulnerability databases. safeguard scan --sbom <file> covers SBOMs from vendors, and safeguard scan --dir . covers repositories. Results land as JSON under ./output. The platform shows which projects contain a given component and version, so you know which services' hosts need the checks above.
  • Proving the rebuilt image is clean of the old runtime. After a rebuild, scan the new image and confirm the PHP package version before it goes live. Policies and gates in the platform can block a build that still carries a vulnerable package.
  • Doing the rebuild with approval. The Safeguard CLI's assistant can edit a Dockerfile to move to a patched base image and run the build and tests, asking before each command under its default permission mode. The desktop and phone apps can send that work to a computer running the CLI and let you approve each command. Autonomous remediation can open fix PRs for application dependencies and is off by default.

Distro backports can make version matching noisy, and databases can lag a same-day advisory, so confirm against your vendor changelog. You can download Safeguard at https://safeguard.sh/download and read the CLI docs at https://docs.safeguard.sh/docs/cli .

Zero-Day Discovery and Gold

Two Safeguard capabilities target the "before the CVE" and "rebuild fast" parts of incidents like this.

  • Zero-Day Discovery looks for previously unknown flaws before a CVE exists, in an agentic mode and a deterministic scanner mode, and issues findings as SGZ advisories before they reach public CVE databases. It covers seven package ecosystems. PHP core and the web server are runtimes outside those ecosystems, so they are not in its scope.
  • Gold Open Source at gold.safeguard.sh is free and needs no login. It is searchable CVE intelligence with CVSS, EPSS, KEV status, affected and fixed versions and a recommended safe version, plus a free read API and a CI gate GitHub Action.
  • Gold Registry at registry.safeguard.sh is the paid side: hardened drop-in components and container images held to zero exploitable critical or high CVEs, SLSA L3+, Sigstore-signed, with evidence pages. An artifact loses its badge if it regresses.

The habit that matters for a compromise response is the one these support: rebuild from patched, signed components pulled from a curated source, rather than repairing a server you no longer trust.

Common mistakes

  • Treating "patched" as "clean". The patch stops new attacks. It does nothing about a web shell written the day before.
  • Deleting a suspicious file before copying it. You lose the evidence that tells you what else to look for. Copy it off the host, then remove it as part of a rebuild.
  • Checking only the host and not the container. A long-running container has its own filesystem. Use docker diff and redeploy from a fresh image.
  • Restoring the old database without checking it. A planted admin account comes back with it.
  • Running public exploit code to "test" your server. Tenable warns that unverified exploit code can contain malware. Use the vendor's version checks instead.

FAQ

I patched PHP2Shell within hours. Do I still need to check?

If the server was internet facing and ran a vulnerable version after the morning of 20 October, yes. Exploitation status is disputed, but watchTowr reported honeypot hits on 21 October, and the NCSC asks organisations that could not update at once to look for compromise.

Are there official indicators of compromise for PHP2Shell?

Not in the sources we read on 21 October. Huntress lists its IOC section as pending, watchTowr's FAQ gives none, and CERT-EU's advisory has no compromise guidance. Behavioural signs from PHP's advisories, Huntress and Wiz are what defenders have for now.

How far back should I review logs?

At minimum from the morning of 20 October until your workers restarted on the patched release. For internet-facing mod_php hosts, go as far back as your logs allow, since the flaws are old and earlier private use cannot be ruled out, even though no source has reported it.

My logs are clean. Am I safe?

Not necessarily. PHP's advisory says a clean log is not proof of safety, and the memory disclosure path may leave no trace. Clean logs plus clean file, process and persistence checks are good news. Still rotate session and application secrets on exposed hosts.

Should I rotate credentials even without signs of compromise?

For internet-facing servers that ran a vulnerable version, it is a sensible precaution because worker memory can hold secrets from other requests, according to The Hacker News and Wiz. Do it after containment if you found anything, so an attacker with access cannot read the new values.

Does the WAF rule mean I can skip this?

No. Cloudflare's CTO called its rules a stopgap, and they only cover traffic routed through Cloudflare, published after details leaked. Any direct-to-origin traffic and anything before the rule went live is outside it.

Fix it without waiting for upstream

In incidents like this one, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.

1. Autonomous remediation: pull requests, not tickets

When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation covers eight categories, including dependencies, licenses, security posture and findings. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.

2. Gold Open Source: the safe version in seconds, free

gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds. The safeguard-sh/gold-scan-action GitHub Action can fail a build on a known exploited vulnerability, on any known vulnerability, or never, so a version you have just removed cannot quietly come back in next week's merge.

3. Gold Registry: start from components that are already fixed

registry.safeguard.sh provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs, zero malware and a completed license check, with SLSA L3 or higher provenance, a Sigstore signature and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.

When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. This fork and patch flow is in early access today, so ask which packages it covers before you plan around it.

Your situationWhat to use
A fixed version existsAutonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version
You need to know today whether you are affectedGold Open Source lookup and "Am I affected?" checker, free and without login
You want vulnerable versions to stop shippingThe Gold scan GitHub Action in CI, plus Safeguard policies and gates
Upstream has no fix yet, or will not ship oneA custom Gold request; fork and patch (early access)
You want to start clean on new projectsPull hardened components and images from Gold Registry

One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.

See how Safeguard would have helped

These demos show real Safeguard sessions, not this incident. Each one shows a flow you would reuse after a PHP2Shell compromise check.

The CLI demo shows the assistant fixing a lodash finding: it reads the advisory, edits the dependency, runs install and tests with your approval and pushes nothing. For a PHP2Shell rebuild, you would ask it to move your Dockerfile to the fixed PHP base image and run the build, then use /scan to check the result. It asks before each command.

Click through it at your own pace, or open it full screen.

This demo sets up the local runner on your own machine, approves it with its device code, and scans from the terminal. After rebuilding a host image from scratch, this is how you would scan the new image locally and confirm the PHP package is on the fixed release before it replaces the old server.

Click through it at your own pace, or open it full screen.

The desktop demo shows a CLI session in the conversation list, a request for work on the computer, a chosen folder, and Approve or Deny on each command and file edit, ending with an upgrade done and tests passing. During an incident you could drive the same Dockerfile change and rebuild for each affected service this way while responders work on the host checks.

Click through it at your own pace, or open it full screen.

Quick check

When does the PHP2Shell exposure window end for a server?

When the PHP workers restarted on the patched binary, not when the package was installed. Check the start time of the FPM master or Apache parent process.

You find an unknown PHP file in the uploads folder. Clean or rebuild?

Rebuild. Copy the file and logs off the host first, then build a new server from a known-good image, deploy the app from source, check the database for planted accounts and rotate every secret the web user could read.

Sources

Last reviewed: 21 October 2026. This is a developing story; check the linked advisories for the latest status.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.