A WordPress backdoor is the reason some hacked sites get cleaned three times in a month. You remove the spam, the site looks fine, and a week later it is back. That is not bad luck. Something is still holding the door open.
This guide covers what a backdoor is, why attackers bother planting one, the eight forms it most often takes, how to hunt for each, and how to take it out without breaking the site. If you are not sure you were hacked at all, start with the signs your WordPress site has been hacked and come back.
What a WordPress Backdoor Actually Is
A backdoor is any hidden way into your site that skips the normal sign-in. It might be a file that runs commands when someone visits a certain address. It might be an extra administrator account. It might be a few lines of code that wait for a secret request.
Think of a house burglary where the thief copies your key on the way out. You fix the broken window, but the copy still works. The backdoor is the copy.
A related term you will hear is web shell: a script that gives the attacker a control panel in their browser, with a file manager and a command box, running as your site. Most web shells act as backdoors.
Why Attackers Plant Them
The first break-in is the hard part. Maybe they used a flaw in an old plugin, or a stolen password. That flaw may get patched tomorrow. A backdoor means they no longer need it.
It also lets them sell access, reuse your server for spam or redirects, and come back whenever they like. Many infections are automated, so a bot plants the backdoor within seconds of getting in and the human behind it checks later.
Key takeaway: Cleaning up what you can see is not the same as closing the way in. Always assume there is more than one backdoor until you have checked every place in this guide.
The Eight Common Forms of a WordPress Backdoor
Here is the quick map before we go through each one. The "where" column is the thing to open first.
| Form | Where to look | Why it survives updates |
|---|---|---|
| Rogue administrator | Users screen | Accounts live in the database |
| PHP file in uploads | wp-content/uploads | Updates never touch uploads |
Code in functions.php | Active theme folder | Updates replace the theme only if you reinstall it |
| Must-use plugin | wp-content/mu-plugins | Not shown in the normal plugin list |
| Fake plugin | wp-content/plugins | Looks like a real plugin |
wp-config.php include | Top or bottom of wp-config.php | Core updates leave that file alone |
| Database-stored code | wp_options, posts, widgets | Files can be perfect and it still runs |
| Scheduled task | WP-Cron list | Recreates the other backdoors on a timer |
1. A Rogue Administrator Account
The simplest backdoor needs no code. The attacker creates a new administrator with a bland name and signs in like anyone else.
How to hunt: Go to Users and filter by Administrator. Every name should belong to someone you know. Also look at accounts that were changed rather than created: an old editor quietly promoted to administrator, or your own email address swapped for another.
Where Stack Guard helps: The activity log records user and role changes with who did it and from which address. Free keeps core events for 7 days, and Pro keeps them longer. Pro also has an alert for a new administrator, so you hear about it straight away.
2. PHP Files in the Uploads Folder
The uploads folder holds images and documents. It should hold no PHP at all. Attackers love it because it is writable by the web server, and a PHP file there can often be run just by visiting its address.
How to hunt: Over SFTP or in your host's file manager, search wp-content/uploads for .php files. From a command line it is one line:
find wp-content/uploads -type f -name "*.php"
Also look for files with double extensions such as photo.jpg.php, and files hidden by a leading dot.
Stack Guard's signature scan skips the uploads folder, and so does file change monitoring, so this is a check to do by hand. The better long-term fix is to stop PHP running in that folder at all, which is a web server setting your host can apply.
3. Code Added to a Theme's functions.php
The functions.php file in your theme runs on every page. A few extra lines there can create a hidden user, accept a secret request, or load code from another site. Because the file is full of legitimate code, a few extra lines are easy to miss.
How to hunt: Open the active theme's functions.php, and any child theme's, and scroll to the very top and very bottom. That is where injected code usually sits. Warning signs are long strings of random characters, eval(), base64_decode(), gzinflate() and str_rot13().
A faster way is to compare with a clean copy. Download the same version of the theme from its source and run a file comparison. Any difference you cannot explain is a finding.
4. Must-Use Plugins in wp-content/mu-plugins
This is one of the nastiest hiding spots. WordPress loads any PHP file in wp-content/mu-plugins automatically, before normal plugins, and per the must-use plugins documentation they do not appear in the default plugin list. They show up in a separate Must-Use section, and you cannot switch them off from the dashboard. The only way to disable one is to delete the file.
So a malicious file in that folder runs on every request, and it will not show up in the Plugins screen you normally check.
How to hunt: Look at the folder directly. Many sites have no mu-plugins folder at all, and an empty one is normal. If you do not use must-use plugins (some hosts add a handful for caching), anything in there deserves a hard look. The Plugins screen also has a Must-Use tab that lists what is loaded.
Where Stack Guard helps: File change monitoring (Pro) covers mu-plugins along with plugins, themes and core, so a new file there shows up as an added file after the next scan.
5. Fake Plugins
A fake plugin is a folder with a believable name, like wp-security-helper or akismet-pro, that contains a backdoor. It might sit in the plugin list looking harmless, or be hidden from it with code.
How to hunt: Compare the Plugins screen with what you actually installed. Then compare the folders in wp-content/plugins with that list. A folder that is not in the screen, or a plugin with no description or author link, is suspicious. Search the folder name online. Real plugins have a page on WordPress.org or a vendor site.
Fake plugins are also how phishing emails try to get in, which we cover in WordPress phishing emails.
6. Includes in wp-config.php
Your wp-config.php file runs before almost everything else, which makes it a high-value spot. A single added line such as include 'wp-content/uploads/cache.php'; pulls a hidden file into every request.
How to hunt: Open the file and read the whole thing, top to bottom. It should be database settings, security keys, the table prefix, and a few define() lines. Any include, require, eval or long encoded string is a problem. Also check the server-level settings that can do the same job, such as an auto_prepend_file line in .user.ini or .htaccess.
7. Code Stored in the Database
Some backdoors are not files at all. The code is stored in the database, and a tiny loader reads and runs it. You can wipe every file and it will still be there.
How to hunt: Look in the options table for large, odd values, especially anything containing eval(, base64_decode or <script. Check widget text, and posts and pages for injected scripts. A search of a database export is the practical way to do this:
wp db export - | grep -c "eval(base64_decode"
A count above zero tells you to look closer. Many legitimate plugins store complex data, so confirm before deleting any row.
8. Scheduled Tasks That Rebuild Everything
WordPress runs background jobs through WP-Cron. An attacker can schedule a job that recreates a deleted backdoor or admin account every few minutes. This is why a cleaned site gets reinfected like clockwork.
How to hunt: List the scheduled events and look for names you cannot match to a plugin you use:
wp cron event list
Without WP-CLI, a cron viewer plugin does the same job. Cryptic names are not automatically bad, so search each one before you act.
How to Hunt for a WordPress Backdoor in the Right Order
Do not start by deleting things. Work through this sequence and the picture builds itself.
- Take a backup of the site as it is. Files and database. You want evidence, and a way back if a cleanup step breaks something.
- Run a malware scan. Let a tool do the first sweep. It will not find everything, but it finds what you would otherwise spend hours on.
- Verify core files. WordPress can compare its own files with the official checksums. With WP-CLI:
wp core verify-checksums. - Check users. Write down every administrator and compare against who should be there.
- Walk the high-risk folders. Uploads,
mu-plugins, the active theme and the plugins list, as above. - Read
wp-config.phpand.htaccess. Both are short. - Check the cron list and the database.
- Look at recently changed files. Sort by modified date and ask about anything from around the time of the first sign of trouble.
Pro tip: Note the date a rogue user was created or a bad file was last modified. That timestamp is the closest thing you have to the time of the break-in, and it tells you which log entries and backups to look at.
What a Scan Can and Cannot Tell You
Stack Guard's malware scanner compares every WordPress core file with the official copy for your version, looks for the signatures of known back doors, web shells, hidden redirects and injected code, and flags extra PHP files in the WordPress folders. Manual scans are free. Scheduled scans are part of Pro.
It is a good first sweep, not a guarantee. Signature scans only find code that looks like something already seen, and, as noted above, they skip the uploads folder. A scrambled, never-before-seen backdoor can slip through, which is why the manual checks still matter. The guide to scanning WordPress for malware shows how to read the results.
How to Remove a WordPress Backdoor Safely
Removal has one rule: replace, do not patch. If you edit a compromised file by hand, you have to be sure you caught everything in it. If you replace it with a clean copy, you do not.
- Replace core. Reinstall WordPress core files from WordPress.org, leaving
wp-contentandwp-config.phpalone. Stack Guard Pro can restore an original core file from WordPress.org when a scan flags it. - Replace plugins and themes. Delete each one and install a fresh copy from its official source. Delete any plugin you do not use. Do not just deactivate it.
- Remove the planted files. Uploads PHP files, fake plugins,
mu-pluginsentries. If you are unsure about a file, move it out of the web folder instead of deleting. Stack Guard Pro's quarantine does this: the file is moved to a locked folder where it cannot run, and you can restore it if it turns out to be needed. - Clean
wp-config.php. Remove the added lines. Some core files,wp-config.phpamong them, are never moved or deleted by the quarantine, so clean those by hand or ask your host. - Delete rogue users. Reassign their content if needed. Do not simply leave them with a lower role.
- Clear the database. Remove the injected rows you confirmed, and delete the scheduled tasks.
- Change every credential. WordPress administrators, hosting, SFTP and the database. Then rotate your security keys, which signs out every session, including any the attacker is holding. Our guide to WordPress salts walks through it.
- Find out how they got in. An old plugin? A reused password? If you skip this, you are cleaning a site that will be hacked again. The same step-by-step is in our guide to recovering a hacked WordPress site.
If the site has a clean backup from before the infection, restoring that and then updating everything can be quicker than a hunt. Make sure the backup really predates the break-in. The Stack Guard backups page explains how backups work and how they are verified.
How to Confirm the Backdoor Is Gone
Cleaning feels done long before it is. Confirm it.
- Rescan. Run a fresh malware scan and check core file integrity again.
- Re-check users and cron. Look again an hour later, then a day later. A recreated user or task means something is still running.
- Set a baseline. With file change monitoring (Pro), create a baseline of the clean site. After that, any new or changed file is flagged on the next scheduled scan. Only do this when you are sure the site is clean, because the baseline treats the site as it is now as normal.
- Watch the log. The activity log shows sign-ins, new users and settings changes. A few quiet days is a good sign.
- Check from outside. Search
site:yourdomain.comon Google and open the site from a phone in a private window. Several infections only show up to outside visitors, as we describe in the WordPress redirect hack guide.
Making the Next Backdoor Harder to Plant
A backdoor needs a way to write files. Remove the easy routes and most attacks fail.
- Disable the dashboard code editors. WordPress has a constant for this,
DISALLOW_FILE_EDIT, which the hardening handbook describes. It will not stop an attacker who can upload files, but it takes away an easy tool. Stack Guard's hardening tab can switch off the theme and plugin editors for you. - Keep plugins and themes updated, and delete what you do not use. Most break-ins start with an old, vulnerable component.
- Use two-factor sign-in. A stolen administrator password stops being enough on its own.
- Tighten file permissions. Core directories should not be writable by the web server. The guide to wp-config and file permissions shows the values.
- Watch for changes. Scheduled scans, file monitoring and alerts mean you notice in a day, not a quarter.
None of this makes a site impossible to attack. It does make a backdoor harder to plant and much easier to spot, and that is the realistic goal.