WordPress Backdoor Removal: Why Hackers Keep Getting Back In
By Glenn Lyvers · Updated · 6 min read
A backdoor is a hidden way back into your website that an attacker plants during a hack, separate from whatever visible damage the malware does. If your WordPress site was cleaned and then reinfected days or weeks later, a leftover backdoor is almost always the reason. Removing the malware you can see is maybe a third of the job. Finding the entry points you can't see is the rest.
I clean hacked WordPress sites every day, and backdoors are where most do-it-yourself cleanups fall apart. Not because site owners are careless. Because backdoors are built to look boring.
What a backdoor actually is
Strip away the drama and a backdoor is just a small piece of code that takes instructions from outside your site. Sometimes it's a full "shell" with a login screen and a file browser. More often it's a single line buried in a file nobody reads, something that decodes and runs whatever an attacker sends it. The classic shape is a call to eval() wrapped around a blob of base64 text, but there are hundreds of variations, and the newer ones are split across several innocent-looking pieces so no single line looks dangerous.
The attacker doesn't need to log in to use it. They send a crafted request to the file, the file does what it's told, and your site is compromised again. From your side, nothing happened. There's no failed login, no new user, no red flag in the dashboard.
Where backdoors hide
After enough cleanups you learn the neighborhoods. These are the spots I check on every single job:
wp-content/uploads— PHP files sitting where only images and documents belong. Uploads folders are writable by design, which makes them the most popular drop zone I see.wp-content/mu-plugins— "must-use" plugins load automatically, need no activation, and never show an Activate/Deactivate link. Most owners have never opened this folder in their life.- Fake core files in the site root — names like
wp-cache.php,wp-info.phporwp-log.phpthat look official but aren't part of WordPress at all. - Code appended to legitimate files — a real plugin file with thirty extra lines at the bottom, or a theme's
functions.phpwith a block that wasn't there last month. - The database — executable code stored in
wp_optionsor in widget content, pulled in and run by a tiny loader file elsewhere. - Access that doesn't look like code at all — a rogue administrator account or an application password added to a real one. That's a backdoor in effect, even though no file is involved.
One more that catches people: scheduled tasks. I've cleaned sites where every file was spotless, but a WordPress cron entry quietly re-downloaded the infection every night. The site was reinfected on a schedule, literally.
Why your scanner didn't catch it
Security scanners match files against signatures of known malware. That works well for the common stuff and fails quietly on anything new, customized, or obfuscated differently than the sample the vendor collected. A backdoor written for your site last week may match nothing in any database.
There's a second problem people don't like to think about. A scanner running inside a compromised site is asking the compromised site whether it's compromised. Malware can and does hide files from the very plugin that's scanning for them. I like Wordfence and recommend it, but on an actively infected site no scanner's clean bill of health means much. My guide to hack detection and indicators covers the signs that matter more than a green checkmark.
How I actually hunt them
The single most reliable technique is comparison. WordPress core files are public, so I compare every core file on the site against a clean copy of the exact same version, byte for byte. Anything that differs gets read. Same idea for plugins and themes that come from the official repositories. Malware can disguise itself from scanners, but it can't hide from a diff.
Next, modification times. Most malware doesn't bother faking timestamps, so a sweep for files changed during a window when nobody was editing the site produces a short, interesting list. Some strains do fake their dates, so I treat a timestamp as a lead, never as proof.
Then pattern searches across the whole hosting account for the usual building blocks — eval, base64_decode, gzinflate, functions called through variables. Plenty of legitimate code uses these too, so every hit gets read in context rather than deleted on sight. Deleting blind is how people break their own sites.
And the parts that aren't files get the same attention: the user table, application passwords, scheduled tasks, the options table, and every other site in the same hosting account. One infected neighbor under the same account can reach across and reinfect a freshly cleaned site. I've watched it happen within hours.
Removing the backdoor isn't the last step
Say the hunt went well. Every planted file is gone, the rogue user is deleted, the cron entry is removed. Two things still stand between you and an actual recovery.
First, the entry point. A backdoor is what the attacker left behind; it is not how they got in. Somewhere there was an outdated plugin, a stolen password, a vulnerable theme, or a neighboring site, and if that hole is still open, you'll collect a fresh set of backdoors soon enough. Part of every cleanup I do is working out the most likely entry point from file dates and logs, then closing it — updating or removing the vulnerable component, not just patching around it.
Second, the secrets. Anything the attacker could read while they had access, assume they read. That means rotating the database password, the WordPress salts, admin passwords, and any API keys on the site. I've written up the full rotation list in my piece on wp-config.php after a hack. Skipping this is how attackers walk back in through the front door after you've bricked up the back one — no malware required, just your own credentials.
On one job a while back, the site was genuinely clean after the sweep, but the owner's database password had been sitting in a readable config backup for months. Reinfection took four days and used no backdoor at all. Rotation would have prevented it entirely.
Cleaned it and it came back anyway?
That's not bad luck. Something survived — a backdoor, a rogue user, a cron job, or an infected neighbor — and it's worth figuring out which before the third round. I wrote a separate piece on why sites keep getting reinfected that walks through the loop in detail.
If you just want a quick read on whether your site is showing signs of compromise right now, my free scanner takes about a minute.
And if you'd rather not spend your week grepping for eval, that's fine too. This is what I do all day. My Bulletproof Cleaning includes exactly this hunt — core comparison, timestamp sweeps, database and user audit, the whole account — because a cleanup that skips the backdoors isn't a cleanup. It's an intermission.
Common questions
What is a backdoor on a WordPress site?
A backdoor is hidden code, or a hidden account, that lets an attacker get back into your site after the visible infection is removed. It's usually a small PHP file or a few injected lines that accept commands from outside. It can also be a rogue admin user or an application password you didn't create.
Why does my WordPress site keep getting hacked after I clean it?
Because something from the first compromise survived the cleanup. The usual suspects are a backdoor file, a rogue administrator account, a malicious scheduled task, or an infected site in the same hosting account. Reinfection within days is almost never a brand-new attack; it's the old one letting itself back in.
Can Wordfence find backdoors?
Sometimes. Wordfence catches known backdoors well, and I recommend running it. But signature-based scanning misses new or customized backdoors, and any scanner running inside an infected site can be lied to by the malware itself. A clean scan result on a recently hacked site is a data point, not a verdict.
Where are WordPress backdoors usually hidden?
The most common spots are PHP files inside wp-content/uploads, the mu-plugins folder, fake core-looking files in the site root, extra code appended to legitimate plugin or theme files, and code stored in the database. Rogue admin users and application passwords serve the same purpose without touching a file.
Do I need to reinstall WordPress to remove a backdoor?
Replacing core files with a fresh copy of the same version is a good move, and I do it on most cleanups. But it isn't sufficient on its own. Backdoors also live in uploads, themes, plugins, the database, and user accounts, so a core reinstall without a full audit still leaves doors open.