Back to Blog
Malware Analysis

How to Identify and Remove Hidden WordPress Backdoors

August 23, 2026
8 min read
WebAdish Security Team
How to Identify and Remove Hidden WordPress Backdoors

Most WordPress backdoors are files — a webshell, a disguised plugin, an injected line in functions.php. Those are the ones every scanner looks for. The backdoors that survive a cleanup are the ones nobody thinks to check for.

The Usual Suspects: File-Based Backdoors

Before the unusual ones, the common categories worth knowing:

  • Web shells — full file-manager tools disguised as plugin files, giving an attacker direct read/write access through a browser.
  • Hidden must-use plugins — placed in wp-content/mu-plugins/, which loads automatically and isn't visible in the normal plugins list.
  • Theme-level droppers — code injected into a theme's functions.php that silently re-creates a deleted backdoor plugin.
  • Cloaker pages — files named to look like real site pages (about-us.php, contact-us.php) that serve spam content only to search engine crawlers.

The Backdoor Category File Scanners Don't Check

WordPress never uses database triggers, stored procedures, or scheduled events on its own. That means any presence of one is automatically suspicious — but it's a category of compromise that standard file-based malware scanners simply aren't built to look for, because they scan the filesystem, not the database schema.

Real case: the admin-account trigger

During a recent 263-site recovery, one client site became completely inaccessible — even the hosting panel's one-click admin login failed, despite every conventional check coming back clean. The cause: a MySQL trigger that silently intercepted any attempt to create a new administrator account, allowing only the attacker's disguised account to exist. Once that account was removed, the trigger made it permanently impossible to create a replacement through any normal means. Read the full case study →

The Scarier Version: A Comment-Activated Backdoor

The same investigation turned up a second trigger on several other sites — one that watched every public blog comment for a specific phrase. The moment that phrase appeared in a comment, something any anonymous visitor could submit, the trigger silently created a full administrator account with a password the attacker already controlled. No login, no file upload, no existing access required — just one public comment.

How to Check Your Own Site

If you have direct database access, a developer can check for unexpected triggers, stored procedures, and scheduled events with standard MySQL queries — SHOW TRIGGERS, SHOW PROCEDURE STATUS, and SHOW EVENTS against your WordPress database. Anything present that you or your development team didn't explicitly create should be treated as a compromise until proven otherwise. This is genuinely not a DIY task past the initial check — safely removing a database-level backdoor without breaking legitimate site functionality requires understanding exactly what the trigger does and what it's connected to before touching it.

Why This Matters Even If You've Already Been "Cleaned"

A site can pass every file-integrity check, have a fully verified WordPress core, and correct file permissions — and still be compromised at the database level. If your site (or your agency's portfolio) has ever been cleaned and you're still not 100% certain it's secure, a database-level check is the gap most cleanups skip entirely.

Frequently Asked Questions

Can Wordfence, Sucuri, or MalCare detect database triggers?

No. These tools are built to scan files and known malicious code patterns, not database schema objects like triggers, stored procedures, or scheduled events. A clean scan result from these tools does not rule out database-level persistence.

How would an attacker even plant a database trigger?

The same way they gain any other access — a compromised admin account, a vulnerable plugin with SQL execution capability, or direct database credentials obtained from a leaked config file. Once they have any way to run SQL, planting a trigger is straightforward.

Is it safe to just drop every trigger I find?

Only after confirming it isn't something your own team or a legitimate plugin created (some plugins do use triggers for caching or logging). Investigate what a trigger does before removing it — but any trigger you can't account for should be treated as hostile.

Does this affect WooCommerce checkout or customer data?

It can. A database-level backdoor with sufficient privileges could theoretically be extended to intercept order or customer data, which is exactly why a full database audit — not just a file scan — matters most for stores handling transactions.

If you manage a portfolio of WordPress sites and have never had the database itself audited — not just the files — that's worth doing before you assume you're secure. Talk to our team →

Found this helpful?

Protect your WordPress site

Get a Security Assessment

Related resources

Continue with the pages buyers usually visit next after reading this topic.

Need Professional WordPress Security?

Our team of WordPress security experts protects 800+ sites. Let us protect yours.

WhatsApp support