Sep 28, 2026 · WPGuard Team

Why Hidden Plugins Evade Your Security Scanner (And What Actually Catches Them)

Why Hidden Plugins Evade Your Security Scanner (And What Actually Catches Them)

Most WordPress security scanners work by calling the same WordPress functions an administrator would use to inspect a site — get_plugins(), the admin plugin list, the theme editor. That works fine against an unsophisticated attack. It fails completely against a plugin that specifically targets those functions.

A real technique we have seen: a malicious plugin hooks the all_plugins filter and removes its own entry from the list any time an administrator views it, while the plugin remains fully active on disk and continues running on every page load. Any scanner that only asks WordPress "what plugins are active" gets the same lie the administrator does.

The fix is structural, not smarter scanning

The only reliable defense is comparing two independent sources of truth: what is actually present on disk in wp-content/plugins/, and what WordPress itself reports through get_plugins(). A mismatch between the two is exactly the signature a self-hiding plugin cannot avoid leaving, because it needs the files on disk to keep running.

This is why WPGuard checks inventory both ways on every scan, rather than trusting a single API call. It is a small technical decision, but it is the one that actually would have caught the incident that led us to build this product in the first place.

If you manage client sites and have never checked disk-vs-database inventory directly, it is worth doing manually at least once so you know what a clean result looks like before you need to spot a compromised one.

This disk-vs-database check is one part of a larger signed-agent security model — see the Security page for the full technical breakdown of how WPGuard verifies every check-in.

See what WPGuard would catch on your site.

Connect a site in a few minutes and get your first inventory scan back immediately.

Try free →