# When a WordPress Plugin Was Backdoored

Canonical: https://vulnify.app/blog/backdoored-wordpress-plugin-what-to-do

A backdoored WordPress plugin is not a normal CVE. Contain the release, keep evidence, replace it from a source you trust, review administrators, and assume secrets in that plugin’s settings may be exposed.

A backdoored WordPress plugin is a release that contains code the publisher, or someone who took over the publisher, put there so outsiders could get in. That is not the same event as a coding mistake with a patch. Updating to “the latest version” can be the attack if the latest version is the bad one, or it can be the cure if a later version removed the backdoor. You have to know which release you are holding before you press update. Ordinary advisories are a version check, not this cleanup. Use this article when the advisory says the code was malicious: a hidden administrator, a token baked into the plugin, a surprise file upload, or an update that phones home. Public scanning will not perform a malware autopsy. The WordPress scanning guide already draws that line. What follows is the owner’s response inside wp-admin and at the host, not a claim that a website scan cleaned the server. Contain before you tidy If the bad release is still active, deactivate it. If you are not sure the currently installed zip is clean, do not update it from the dashboard button until you have checked the vendor’s own incident note for the exact safe version. Dashboard updates pull whatever the plugin directory is serving. During an incident, that directory is part of the question. Take the site offline or block the specific plugin’s PHP files at the web server if the backdoor is unauthenticated and the site is still serving traffic. A payment or membership site that stays up while you “gather info” is giving the backdoor more time. Write down the time you contained it. You will need that time when you look at users and files created after the bad release was installed. Keep evidence before you delete the only copy Export a copy of the plugin folder and a list of administrator accounts before you delete everything in a panic. Your host’s file manager or a staging copy is enough. You are not building a forensic lab. You are keeping the version string, the file names, and the user list so you can answer “what was installed” next week. Deleting the folder first is how teams forget which release they had. Do not upload that folder to a random scanner site, and do not paste its PHP into a chat. Secrets and the backdoor travel with the files. Store the copy where you already keep backups, with access limited to the people handling the incident. Replace it from a source you trust Read the vendor’s incident post, not a repost. Note the last known-good version and the first cleaned version. If the project tells you to delete the plugin and wait, do that. Installing a “nulled” copy or a mirror from a forum repeats the supply-chain failure. If you must restore function, pick a different maintained plugin, or a feature in WordPress itself, rather than an unofficial zip of the same slug. After the clean copy is in place, confirm the version in wp-admin and confirm the unexpected file named in the advisory is gone. A public check with the WordPress stack checker can show whether the old plugin path is still linked from the theme. It cannot promise the disk is clean. Pair it with public compromise signals so you see Safe Browsing and redirect symptoms, then keep looking in the admin. Review administrators and other privileged users Open the user list and sort by registration date. A backdoor’s usual goal is a new administrator, or a quiet role change on an existing user. Remove accounts you cannot explain. Reset passwords and sessions for every remaining administrator, editor, and anyone who can install plugins. Logging those people out matters because a stolen session cookie survives a password change until the session store is cleared. Check application passwords and any “remote publishing” tokens the bad plugin could have created. xmlrpc.php and the users route are separate hardening items, listed in the 15 checks before you go live , but they are how a leftover interface keeps accepting the old password after you have moved the humans to a better login. Close what you do not need as part of this cleanup, not as a substitute for removing the rogue admin. Assume the plugin’s settings were readable If the backdoor could run PHP as the site, it could read wp-config.php and the options table. That means database credentials, authentication salts, and any API keys the plugin stored for mail, payments, or storage. Rotating the WordPress admin password is not enough. Rotate those keys at the provider, then put the new values in using a method you trust. Exposed files on the public site are a related check, covered in exposed deployment artifacts , but a backdoor does not need the file to be publicly linked in order to have read it from disk. Tell the payment or email provider if those keys were in the compromised plugin. They can tell you whether the key was used. You cannot see that from the website homepage. Look for persistence you can actually see In wp-admin, review scheduled tasks, must-use plugins, and the uploads directory for PHP files that do not belong in a media library. A new administrator plus a PHP file in uploads is a pattern, not a coincidence. Unexpected cron events that call a plugin you removed are a reason to delete the event and look for the file that registered it. Stop there for a public-scan workflow. Files outside the site, a compromised hosting panel, and malware that reinfects from another account on the same server are a host investigation. Say that clearly so nobody expects the next Vulnify run to certify the server. The next run should confirm the public plugin footprint and the absence of the known bad path. The host work is a different ticket. Tell the people who were exposed If customer accounts or payment keys were in reach of the bad release, decide the same day whether customers need a password reset and whether the payment provider needs the old key revoked. Waiting for a perfect timeline usually means waiting too long. You can say what you know: which plugin, which dates it was installed, and what you have already rotated. You do not need to publish the PHP. Write the incident in the same place you keep other maintenance notes: the version you removed, the version you installed, the administrators you deleted, and the keys you rotated. The next brief about this plugin should be readable against that note. Otherwise a later update will look clean on a site that still has the rogue user from the first incident. Frequently asked questions Is updating enough? Updating is enough only when you move from a bad release to a release the vendor has said is clean, and you then review users, sessions, and secrets the bad release could have touched. The version number alone does not rewind those actions. Will a website scan remove the backdoor? No. A public scan can show leftover plugin paths, odd redirects, and Safe Browsing warnings. Removal is a file and user action on the site you administer. Should I restore last night’s backup? Restore a backup taken before the bad release was installed, if you have one and you know that date. A backup taken after the bad release may contain the backdoor and the rogue administrator. Check users again after the restore.
