wp-cli/checksum-command
Verifies WordPress file integrity by comparing installed files against WordPress.org's published checksums. Use wp core verify-checksums to detect tampered or missing core files, with options for version, locale, exclusions, and output formats.
wp-cli/checksum-command ships bundled with WP-CLI — there is nothing to install for a normal environment. Confirm it is available and see the surface area first:
wp cli version
wp help core verify-checksums
wp help plugin verify-checksums
If you are on an older bundled version and want the newest release (v3.0.1 adds parallel plugin checksum downloads):
wp package install [email protected]:wp-cli/checksum-command.git
First use case: prove the integrity of an inherited WordPress install before you touch it. Run from the WordPress root (or pass --path=):
wp core verify-checksums # success => "Success: WordPress installation verifies against checksums."
wp plugin verify-checksums --all # success => "Success: Verified 8 of 8 plugins."
Exit codes are the contract: 0 means verified, non-zero means drift. That single fact is what makes this package useful to a Laravel developer — it turns "is this site tampered with?" into a boolean you can assert in a deploy script, an Envoy task, a Forge/Envoyer deployment hook, or a CI job.
Where to look first: the two command docs (core and plugin), then --format=json output, then --exclude. Those three cover 90% of day-to-day use.
Pre/post-deploy gate. Because verification never loads WordPress, it is safe to run early and cheaply. In an Envoy task or a shell deploy script:
set -euo pipefail
wp core verify-checksums --version="$(wp core version)" --locale=en_US
wp plugin verify-checksums --all --format=json > /tmp/plugin-checksums.json
Run the core check after composer install / file sync but before cache flushes and migrations, so a corrupted rsync never reaches production.
Machine-readable output for pipelines and dashboards. --format=json (and csv/yaml/count) is the integration point. Parse and fail deliberately:
drift=$(wp core verify-checksums --format=json --exclude="readme.html,wp-config-sample.php" || true)
if [ "$(echo "$drift" | jq 'length')" != "0" ]; then
echo "$drift" | jq -r '.[] | "\(.file): \(.message)"'
exit 1
fi
--format=count gives you a single number, handy for alerting thresholds. Note the default for core is plain while plugin defaults to table — always pass --format explicitly in scripts.
Fleet sweeps via WP-CLI aliases. With wp-cli.yml aliases for @staging / @prod, verify many sites in one pass:
for site in @site-a @site-b @site-c; do
wp "$site" core verify-checksums --format=count || echo "DRIFT: $site"
done
Targeting specific versions and locales. WordPress.org publishes per-version, per-locale checksum sets. When verifying a site that is not on the default locale (e.g. ja, de_DE), pass --locale matching Dashboard → Updates, otherwise you get warning noise. Similarly --version=6.4.2 lets you verify an install whose DB reports a version different from the files on disk — useful when diagnosing a half-finished core update.
Plugin-level auditing in CI. Use --strict in CI to catch even "soft" changes like readme.txt edits that normal mode tolerates, and --exclude-mu-plugins when your repo vendors mu-plugins separately (they typically have no wordpress.org checksums):
wp plugin verify-checksums --all --strict --exclude-mu-plugins --format=json
Security hygiene integration. Combine with wp core version, wp plugin list --status=active --format=json, and hashes you store yourself to build a signed baseline: verify against wordpress.org first, then diff the set of installed plugins against your composer manifest. Anything present but not in Composer is worth a human look.
Composer-managed WordPress. If you install core via roots/wordpress / johnpgh/wordpress and plugins via WPackagist, verify-checksums is a sanity check that the installed tree still matches upstream published hashes — a cheap guard against a partially-applied composer update or a wp-content directory that got hand-patched.
--exclude="advanced-custom-fields-pro,gravityforms".--exclude takes slugs/paths, comma-separated. Values are trimmed as of v2.3.7, but quoting and whitespace around commas in shell scripts still bite — generate the list programmatically and single-quote it.--include-root is noisy by design. It verifies the WordPress root and warns about any non-WordPress items (your composer.json, .env, wp-cli.yml, deploy artifacts). It does not descend into wp-content. Leave it off in normal runs; turn it on for forensic audits.ja install verified without --locale=ja reports wp-includes/version.php, readme.html, and wp-config-sample.php as mismatched. Always pin --locale and --version from the admin Updates screen.--insecure disables TLS validation for the checksum download. It is a last resort for broken CA bundles in containers. Prefer fixing the container's ca-certificates; --insecure invites a MITM to feed you checksums that match the attacker's files.--insecure-free egress to api.wordpress.org and wordpress.org, or vendor your own verification step.--strict changes the meaning of "clean." Without it, readme-only diffs are tolerated; with it, they fail. Pick one policy per pipeline and document it, otherwise two CI jobs will disagree about the same install.wp-config.php salts, plugins, or constants. That is the safety feature, but it also means it cannot verify plugin behavior or database contents, only files on disk.core verify-checksums fail confusingly. Cross-check wp core version against $wp_version in wp-includes/version.php and use --version= to isolate which side is wrong.wp-content/advanced-cache.php or installer drop-ins; those live outside core checksums, but a modified wp-config.php in root shows up under --include-root.core verify-checksums / plugin verify-checksums via WP_CLI::add_command. Fork it (MIT) if you need a custom source of checksums — e.g. your own signed manifest for private plugins — and add a sibling command rather than patching the existing one, so future wp package install updates do not clobber your changes.--debug to see the WP-CLI request/download trace, and test the same invocation with --format=json to get the exact file list instead of scrolling prose warnings.How can I help you explore Laravel packages today?