Add wp-ops malware-scan for remote WordPress malware scanning - #228
Merged
Conversation
The scanners were reachable by hand only for a site whose files are already on this machine. Scanning a remote one meant scp-ing the scanner to /tmp, running it over SSH, then remembering to delete it -- and since 5.22.0 that does not work at all: both scanners require_once the sibling checksum-verify.php, so a lone copied file fatals on the missing module. The remote-with-checksums path existed only inside the security_scan MCP tool. malware-scan.sh ports that logic to the CLI. It inlines the checksum module in place of the require_once and streams the assembled, self-contained source to php /dev/stdin on the target, so nothing is written to the server and nothing needs cleaning up. /dev/stdin rather than the conventional - because Ubuntu/Debian's packaged PHP CLI treats - as a literal filename (issue #222). Host and path default from the MCP server's site registry when one exists, so a site whose SSH host is not its own domain needs no flags, and fall back to the stock Trellis layout otherwise. Only those defaults assume Trellis: --host and --path aim it at any SSH-reachable WordPress.
The documented remote workflow was to scp scanner-targeted.php to the server and run it there. That has been broken since v2.0 of the scanners: they require_once the sibling checksum-verify.php, so a lone copied file fatals on the missing module. Both remote sections now point at wp-ops malware-scan. The copy-by-hand route survives only as a note that both files have to travel together.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
wp-ops malware-scan— a single command that runs the WordPress malware scanners against a remote site, with checksum verification, from your own machine.The scanners were reachable by hand only for a site whose files are already local. Scanning a remote one meant
scp-ing the scanner to/tmp, running it over SSH, then remembering to delete it. Since 5.22.0 that no longer works at all: both scannersrequire_oncethe siblingchecksum-verify.php, so a lone copied file fatals on the missing module. The remote-with-checksums capability existed only inside thesecurity_scanMCP tool.wp-cli/security/malware-scan.shports that logic to the CLI. It inlines the checksum module in place of therequire_onceand streams the assembled, self-contained source tophp /dev/stdinon the target, so nothing is written to the server and nothing needs cleaning up./dev/stdinrather than the conventional-, because Ubuntu/Debian's packaged PHP CLI treats-as a literal filename (#222).Usage
SSH host and WordPress path default from the MCP server's site registry (
mcp-server/config/sites.json, or$WP_OPS_SITES_CONFIG) when one exists — so a site whose SSH host is not its own domain needs no flags — and fall back to the stock Trellis layout (web@<site-name>,/srv/www/<site>/current/web/wp) when it does not. The registry is gitignored and never embedded in release binaries, so the lookup is entirely optional and degrades silently.Only those defaults assume Trellis. The scan itself is plain SSH plus a PHP CLI:
environment=developmentis the one Trellis-only path, running inside the project's Trellis VM viatrellis vm shell.Naming
security-scanwas taken bytrellis/monitoring/security-scan(Nginx log analysis), and a second entry under that basename would have made both ambiguous to the bare-name dispatcher.malware-scankeeps both resolvable and describes what it actually does.Changes
wp-cli/security/malware-scan.sh— new commandwp-cli/security/README.md— both remote-scan sections rewritten; they still described thescp scanner-targeted.phpworkflow that has been broken since v2.0 of the scanners. The copy-by-hand route survives as a note that both files must travel together.go/internal/catalog/catalog.json— regenerated (go generate ./...)go/internal/catalog/catalog_test.go— entry count 79 → 80CHANGELOG.md— 5.23.0Verification
bash -nunder both bash 5.3 and macOS's bash 3.2;shellcheckclean apart from two informational notes (theEXITtrap function, and the deliberate client-sideprintf %qquoting)php -l, with zero remaining references tochecksum-verify.phpphp /dev/stdinagainst a local WordPress: checksum verification ran, 3,338 files verifiedwp-opsdispatch: resolved host and path from the registry, 1,955 checksum-verified files skipped, 0 checksum failures, no threatsgo test ./...passeswp-ops malware-scanresolves by bare name andwp-ops security-scanstill resolves to the existing playbookNote
The scanners close with a "DELETE THIS FILE after use" warning that does not apply to this path — nothing is copied to the server. The README now says so. Changing the scanners' own output was left out of scope since it affects every other invocation route.