WordPress legitimately changes cache, uploads, logs and update files. A useful alert system prioritises executable or configuration changes and can tie them to an approved deployment; alerting on every thumbnail creates fatigue.
Baseline the clean release and define path-specific expectations.
Establish a clean baseline
Record hashes/versions for WordPress core, plugins, themes, must-use plugins, drop-ins and configuration structure after recovery acceptance.
Store the baseline outside the web account with restricted access. Exclude secret values while retaining path/owner/mode metadata.
Document generated/writable directories separately.
Prioritise executable paths
Urgently investigate new/changed PHP under core, plugins/themes/mu-plugins, root bootstrap and especially uploads/cache/backup directories where PHP is unexpected.
Changes to wp-config.php, .htaccess, PHP auto-prepend, cron scripts and deployment hooks also deserve high priority.
Do not open suspicious files through the browser.
Interpret writable-directory changes
Images, thumbnails, cache and temporary files change frequently. Alert on executable extensions, server-rule files, unusual double extensions and permissions rather than all content.
Customer uploads can be sensitive; do not copy them into alert systems. Validate file types and block execution where business functionality permits.
Rebuild generated cache instead of trusting it.
Correlate with approved changes
Compare alert time/path with deployment ID, WordPress update, administrator action, backup restore and hosting file-manager/SFTP/SSH logs.
A valid update should have known source, actor and expected file set. A familiar username may still use a stolen credential, so verify the change owner.
Record missing logs as uncertainty.
Compare with trusted sources
Verify official core checksums and exact plugin/theme vendor packages where possible. Review custom code against source control.
An unchanged hash does not prove a version is secure; check vulnerability status. A changed custom file is not malware until ownership is understood.
Preserve suspicious copies before replacement.
Watch recurrence
If a file returns after deletion, record exact hash/time and inspect WordPress/Action Scheduler/server cron, must-use code, database loaders, deployment and account access.
Do not repeatedly delete it and destroy timestamps. Contain the site if the file is active.
Check sibling sites sharing the system user.
Monitor the monitor
Protect the baseline, agent configuration and external destination from the same hosting account. Alert when collection stops, exclusions expand or baseline is replaced without approval.
Require a named reviewer before accepting a new baseline after updates. Otherwise malicious changes can be reclassified as normal.
Test clock/timezone and log delivery so correlation remains usable.
Tune severity and noise
Use critical alerts for configuration/executable privilege paths, medium for unplanned package changes and low/aggregate for expected generated files.
Suppress only known deterministic patterns with owner/review date. Do not exclude entire wp-content because cache is noisy.
Alert through an independent channel with acknowledgement.
Check backups and deployment sources
A file can return from a clean-looking deployment ZIP, backup restore or shared build artifact. Search repositories/releases and backup sets for the same hash/path.
Remove malicious/abandoned code from the authoritative source, not only production. Keep incident evidence separate from operational packages.
Verify the next scheduled deployment/restore in isolation.
Respond with evidence
Capture path, hash, owner/mode, time, baseline difference and source logs. If malicious, preserve snapshots, contain, close the vector and rotate exposed credentials.
If legitimate, link it to the deployment/update and update baseline after tests. Never whitelist an unexplained file merely to silence alerts.
Keep customer data and secrets out of tickets.
Verify the monitor
Run a controlled non-production or safe test change and confirm detection, actor correlation and escalation. Check the monitor continues after cache/log rotation and cannot be disabled silently by WordPress alone.
Request recurring file-integrity care when custom code and several sites create alert fatigue. Share paths/hashes and redacted events—never malware, credentials or customer files publicly.