WordPress file integrity check: was your plugin code changed?

WordPress.org publishes a fingerprint for every file it ships. Comparing your files with those fingerprints is the fastest way to know whether anyone changed your code.

Five rows of files, each with a fingerprint; four are ticked, one is highlighted with a cross because it no longer matches.

A backdoor has to live somewhere. Usually that is an edited plugin file, a new PHP file dropped into a plugin or into wp-content/uploads, or a changed wp-config.php. A file integrity check finds all three, without guessing at what malware looks like.

The fingerprints WordPress.org already publishes

  • WordPress core: https://api.wordpress.org/core/checksums/1.0/?version=7.1.2&locale=en_US lists the MD5 of every core file for that version and language.
  • Every plugin in the directory: https://downloads.wordpress.org/plugin-checksums/{slug}/{version}.json lists the MD5 and SHA-256 of every file in that release.

If your file's fingerprint matches, it is byte for byte what WordPress.org published. If it does not, something changed it.

Check by hand with WP-CLI

wp core verify-checksums
wp plugin verify-checksums --all

The first checks WordPress core; the second checks every plugin installed from the directory. Each lists files that do not match, and files that should not be there.

Where it falls short: it runs only when someone remembers to, it needs shell access, premium plugins and themes have no published fingerprints, and it says nothing about PHP files hiding in uploads.

What a complete check covers

Part of the siteCompared with
WordPress coreWordPress.org's core checksums
Directory pluginsWordPress.org's plugin checksums for the installed version
Themes, premium and custom pluginsThe first copy you trusted: any later change is named
wp-config.php, .htaccess, must-use plugins, drop-insThe first copy you trusted
wp-content/uploadsShould contain no PHP at all

Every day, without thinking about it

Touchstone runs exactly this check every day, in the background, and names any file that changed:

  • A change in a part you have not opened to a developer is a serious finding, emailed within the hour.
  • A change in an area you opened, such as the theme your developer is working on, is noted quietly.
  • If the file is later put back exactly as it was, the finding says so, and still waits for you to acknowledge it.
  • No file contents leave your site: only plugin slugs and versions are sent, to WordPress.org.

The one thing a file check cannot see

If a malicious release is published by the plugin's own author, the bad files are the official files, and the fingerprints match. That is what happened with the EssentialPlugin backdoor. The signal there is earlier: the plugin changing hands. That is why Touchstone watches ownership as well as code.

Related: how to lock the plugin editor and how to check who owns a plugin.