WordPress file integrity check: compare with the official copies
A changed file in WordPress core or a plugin is easy to miss. The site loads, the dashboard looks normal, and nothing tells you that a file in a plugin folder is no longer what its publisher shipped. A WordPress file integrity check answers that question: it compares each file with a known copy and lists what differs.
For core and directory plugins, WordPress.org publishes checksums to compare against. BetterShield, a free security plugin, runs that comparison every hour, shows you the changed lines, and puts the official file back when you ask, keeping yours in quarantine.
Quick summary
- Core and directory plugins are compared with the copies WordPress.org publishes. Your theme, wp-config.php, .htaccess and similar files are compared with their own earlier state.
- Core and directory plugins are checked every hour, in steps on a large site; watched files once a day (hourly with Ultra). Check now starts one yourself.
- The report is under BetterShield › Activity › File changes.
- Show the difference shows the changed lines. Put the official file back restores the published copy and keeps yours in quarantine.
- A deliberate edit, or a plugin’s whole group of changes, can be marked Expected. A later change is still reported.
Why a changed core or plugin file matters
Core and plugin files are code your site runs. Nobody needs to edit them in place, and an update replaces them anyway, so modified WordPress files are always worth a look.
Sometimes the change is a developer’s deliberate edit. Sometimes it is code somebody else put on your site. For core and directory plugins, the check shows you exactly which lines differ, so you can tell which. It also looks for files nobody published, such as a new PHP file in a plugin folder that is not part of any release.
How a WordPress file integrity check works
A checksum is a short fingerprint of a file’s contents. Change one character and the fingerprint changes. WordPress.org publishes checksums for each core version and language, and for each version of each directory plugin. Those WordPress checksums are the official answer to compare against.
To verify WordPress core files, the check works out each file’s checksum on your server and compares it with the published one. Each file it reports is one of these kinds:
| Kind | Meaning | Severity shown |
|---|---|---|
| Altered | Differs from the official copy, or from what it was. | Critical |
| Not published | Nothing published this file. | Critical |
| Missing | A file the official copy lists is gone. | Medium |
| Could not be read | The server would not let it be read: a permissions problem, not a change. | Low |
| Package | A plugin update did not match its published copy when it arrived. | High |
What BetterShield 1.1.0 compares
| What | Compared with | Can be put back |
|---|---|---|
| WordPress core | The checksums WordPress.org publishes for your version and language | Yes |
| Plugins from the WordPress.org directory | The checksums for the exact version installed | Yes |
| Your active theme (and its parent), must-use plugins, drop-ins, wp-config.php, .htaccess, .user.ini files, and plugins not in the directory | What the file was at the last check | No |
WordPress.org publishes no checksums for themes or for premium and custom plugins, so those are watched instead. The first check records their code files, and later changes are reported, except an update WordPress itself installed. Uploads are never checked.
Anything that could not be compared, such as a plugin outside the directory, is named in a note on the report with the reason. Nothing on that note is counted as clean.
When the check runs
- Every hour for core and directory plugins, in the background. On a large site one full check can take several hours, and the screen shows its progress.
- Once a day for watched files: your theme, must-use plugins, drop-ins, wp-config.php, .htaccess and plugins outside the directory (every hour with Ultra).
- Check now starts a check with freshly fetched checksums, or carries on the one already running.
- When a plugin is installed or updated, the download is compared with the published copy before it replaces the old files. This never stops an update.
While changes are open, Findings shows Files no longer match the official copies, with Open the file report. If nothing is open and no check has finished for two days, it shows Files have not been checked against the official copies.
The requests to WordPress.org carry version numbers, your language, plugin slugs and, for one file, its path. They never carry your site address or file contents. See What BetterShield contacts.
Read the report on Activity › File changes
Go to BetterShield › Activity › File changes. The tab reads Files.
Files at a glance shows Last check (with the next run), Unresolved changes, Can be put back and In quarantine. Below it, each file shows its path, when it was Noticed, what it was compared against, and its kind.
Files are grouped under Can be put back, Plugins that differ from their published release and No official copy to put back, with the reason given once per group.
Show the difference, then decide
On an altered core or directory plugin file, press Show the difference. BetterShield fetches the official copy and shows it beside yours, line by line. A long file shows only the part that changed.
Read the changed lines before anything else. If you or your developer made the edit, you will usually recognize it. If you do not, putting the official file back is the safer default, because nothing is lost.
Put the official file back
- Press Put the official file back on the changed file.
- BetterShield fetches the official copy, checks it against the published checksum, and writes it in place.
- Your file moves to quarantine, and the confirmation says this can be undone.
The file you replaced is kept, never deleted. Under Kept in quarantine, Put this file back restores it byte for byte, and the difference is reported again: that is the undo. Download a copy saves it as a .txt file, and Delete, then Yes, remove it for good, removes it permanently. Both are recorded in the activity log.
Only an altered core or directory plugin file gets the restore button. To replace a missing file, reinstall. For code nobody publishes, restore from your own backup, because earlier contents are not kept. Files over 2 MB cannot be compared or put back here.
Mark expected changes
Some changes are yours. Press Expected on a file to stop reporting it as it is now. If it changes again, it is reported again. It moves to Marked expected, where Stop ignoring brings it back.
A plugin update’s group of changes
After an update or a deploy, one plugin or theme can account for many changes at once. By plugin and version lists each one with open changes at one recorded version:
- Check again (plugins only) compares the open changes with the installed version’s published copy once an update has finished. What matches closes.
- Mark all 12 changes expected… (the button shows your count) lists the counts and names the added files that can run as code. Read those, then press Mark these 12 changes expected to mark them as one decision with one undo.
- Marked expected together lists those decisions, and Report them again undoes one.
If you built or patched a plugin yourself, its Package row offers Adopt this copy. That version stays quiet until one of its files changes, and Undo appears in the confirmation line.
When file changes and access line up
BetterShield joins related records into an incident, such as a new administrator and a new PHP file on the same day.
A new PHP file in WordPress core, a plugin, a theme, a must-use plugin or a drop-in can open an incident; the screen calls these records anchors. A changed PHP file joins an open incident as supporting evidence. Records join when they fall within 24 hours of one of its anchors, or share its recorded account or file.
An incident is a correlation, not a verdict. It gives you one timeline to review, and its response plan can put back the checksum-verified copy of a changed core or plugin file. See Incidents.
From the terminal: wp bettershield integrity
wp bettershield integrity shows when the check last ran and what differs. scan runs the check now, and restore --id=<change> puts the published copy back and prints an undo token. suppress, unsuppress, recheck, expect and undo cover the rest, as listed in WP-CLI commands.
A command that changes the site needs --user=<login>. In a deploy script, --fail-on-changes exits non-zero when any file differs, and --strict also fails when something could not be checked.
wp bettershield integrity scan --fail-on-changes
wp bettershield integrity restore --id=12 --user=admin
Common mistakes
- Marking a change expected without reading it. Press Show the difference first.
- Skipping the named code files in a group. When marking a whole plugin’s changes, the added files that can run as code are the ones worth a look.
- Deleting a quarantined copy straight away. It holds what that file contained, which may be what explains the change. Download a copy first if you are unsure.
- Reading “no official copy” as clean. Themes and plugins outside the directory are watched, not verified, and earlier contents are not kept. Keep your own backups.
Frequently asked questions
Does a file integrity check find malware?
It does not give a verdict on what a change means. It reports files that differ from the official copies, files nobody published and files that went missing, and shows you the changed lines. Whether a change is a deliberate edit or code somebody else put there is your call.
Can BetterShield check my theme?
It watches your active theme and its parent for changes, but WordPress.org publishes no checksums for themes. So a change is reported, with no official copy to put back. Restore a theme file from your own backup.
Will an ordinary plugin update show up as a change?
Not normally. A directory plugin is compared with the checksums for the version installed, and an update WordPress itself installed is not reported for watched code. If changes remain from the version you had before, Check again closes the ones that match.
Is the file check part of the free plugin?
Yes. The file integrity check, quarantine and the WP-CLI commands are in the free BetterShield plugin on WordPress.org, with no account needed.
Conclusion
Checking WordPress files against the official copies turns a vague worry into a short list: which files differ, which lines changed, and what you can put back. Every file BetterShield replaces is kept, so nothing is lost.
Open BetterShield › Activity › File changes, press Check now, and work through what it finds. The full reference is the File changes guide, and the WordPress security checklist covers the rest of the audit.