How do I remove malware from my WordPress site?
Quick answer
To remove malware from WordPress properly, work in a careful order rather than panicking. Take the site offline or into maintenance mode, take a full backup, then scan every file and the database for injected code, unknown admin users and modified core files. Remove the malicious code, replace WordPress core, plugins and themes with clean copies, reset all passwords and salts — then find and close the entry point so it can’t come back. If you’re not sure you got all of it, that last step is where most DIY clean-ups fail.
Key takeaways
- Back up first — even an infected site — so you have something to compare against and roll back to.
- Replace WordPress core, plugins and themes with fresh copies rather than trying to hand-clean each file.
- Reset every password, all salts, and check for unknown admin users the attacker may have added.
- The clean-up isn’t finished until you find HOW it got in and close that hole — otherwise it reinfects.
On this page
- First, don’t panic — and don’t delete everything
- Find what’s infected
- Clean it properly
- Then close the door
- What this means for you
- Where malware actually hides in your database
- Reading server logs like a professional does
- Spotting obfuscated and encoded payloads
- Diffing against known-good copies
- Testing before you bring the site back live
- Common DIY mistakes that make things worse
- Talking to customers and stakeholders during the clean-up
- What a complete clean-up actually looks like
- Get help to remove malware from WordPress
First, don’t panic — and don’t delete everything
A hacked WordPress site feels like an emergency, but wiping it blindly usually makes things worse. Put the site into maintenance mode so visitors and Google aren’t served malware, then take a full backup of files and the database exactly as they are. You want a snapshot to work from and compare against.
Find what’s infected
Malware hides in a few predictable places: injected code at the top of PHP files, fake files disguised with innocent names, modified WordPress core files, rogue admin accounts, and injected rows in the database (often in wp_options or post content). Compare your core files against a fresh copy of the same WordPress version — anything that doesn’t match is suspect.
Clean it properly
The reliable way isn’t to hand-edit every infected file — it’s to replace. Reinstall WordPress core from a clean download, reinstall plugins and themes from their official sources (delete anything you don’t recognise), then carefully clean the database of injected content. Reset every password, regenerate your security salts, and remove any admin user you didn’t create.
Then close the door
This is the step that separates a clean-up that lasts from one that reinfects in a fortnight. Most infections don’t come from some elaborate exploit — they come from an outdated plugin, a weak or reused password, or a vulnerability that was patched months ago but never applied. Find that specific entry point and close it, or you’ll be doing this again.
What this means for you
If the site is business-critical, or it has already been cleaned once and came back, that’s the moment to get someone who does this for a living. I’ve removed malware from more than 10,000 WordPress sites — and the pattern is always the same: the clean is the easy part, finding the door is the job.
Where malware actually hides in your database
File infections get most of the attention. But to remove malware from WordPress properly, you can't stop at files. The database has its own hiding spots. Attackers rely on this. Most site owners never think to check there at all.
The options table is a favourite target. It's meant to store settings, not code. A rogue autoloaded row can carry a payload. That payload can run on every single page load, silently, in the background.
Check the site address values too. A common trick quietly swaps these to a lookalike domain. Visitors get redirected without a single file ever changing.
Post content is another common spot. Injected script tags get slipped into old, forgotten posts. Nobody checks those pages regularly. Sometimes entire hidden pages appear there instead. They exist only to serve spam links, or to push visitors toward another site.
Then there's user meta. This is where account capabilities live. It's the setting that decides who counts as an administrator. A hacker doesn't always need a new, visible user. They can simply grant admin rights to an account that already looks harmless.
Comments and term data get overlooked too. Spam comment fields sometimes carry executable payloads, not just link spam. A thorough attempt to remove malware from WordPress checks every table that accepts input. Not only the obvious ones.
Skipping the database is the fastest way to remove malware from WordPress on the surface. The front end looks fine. The infection is still running quietly underneath, waiting for the next chance to spread.
Transients and cron jobs deserve a look too. Malware sometimes schedules its own tasks using WordPress's built-in cron system. That task can quietly reinfect files you already cleaned. A full attempt to remove malware from WordPress has to check scheduled tasks. Not just static content sitting on disk.
Reading server logs like a professional does
Most DIY clean-ups skip the logs entirely. That's a mistake. Logs tell you when the infection actually started. They don't just show where it ended up. Without that timeline, you're guessing blindly at the real entry point.
Access logs show which URLs got requested, and exactly when. A flood of POST requests to an unfamiliar file is a strong clue. It's an even stronger one when a plugin folder changes minutes later.
Error logs often catch the exact script that failed. A single warning line can point straight at the file an attacker used. That's a shortcut most DIY attempts never take.
File modification timestamps matter just as much. Sort every file by the date it last changed. A batch of files all touched in the same second rarely happens through normal use.
Especially at 3am. That pattern points straight at automated tampering, not a person clicking around inside the dashboard.
This is one of the quieter parts of a proper clean-up. No plugin can do it for you. Logs need a human reading them in context. A scanner just ticks boxes against known signatures, and misses everything else.
Login logs matter just as much as file logs. A successful login from an unfamiliar country, at an odd hour, often marks the real starting point. Cross-reference that timestamp against every file change that followed it. The pattern usually explains itself once you line the two up.
Spotting obfuscated and encoded payloads
Not all malicious code looks obviously malicious. A lot of it is deliberately disguised to survive a quick scan. This is exactly where a casual attempt to remove malware from WordPress usually falls short.
Common tricks include base64 encoding and gzip compression wrapped around ordinary PHP. Functions get chained together specifically to hide their real purpose. A single short line might decode into hundreds of lines of working, malicious code.
Attackers also split payloads across multiple files on purpose. One file holds encoded data. A separate file decodes it and runs it. Neither file looks dangerous sitting on its own. That's exactly the point of splitting it that way.
Recognising these patterns takes practice. It's built up over many infections, not from a single checklist. You start noticing odd variable names. You notice unusual string concatenation.
You notice code that serves no visible function anywhere on the front end. It just sits there, quietly doing something else entirely.
Automated scanners catch the well-known signatures fine. They miss custom, hand-written obfuscation almost every time. That gap is exactly where a professional eye earns its keep. A real attempt to remove malware from WordPress has to close that gap.
Some payloads only activate for specific visitors. They check the user agent, or the referrer, before running. A scan from your own browser can come back clean while real visitors still get redirected. That's a technique DIY tools rarely account for.
Search engines eventually catch what a quick scan misses. A payload left running quietly still gets flagged over time. That delay is exactly why a surface-level attempt to remove malware from WordPress rarely holds up for long.
Diffing against known-good copies
The single most reliable technique to remove malware from WordPress is comparison, not inspection. Take a fresh, known-clean copy of the same core, theme, and plugin versions. Compare it file by file against the live site.
WordPress core has official checksums you can verify an install against. Anything that doesn't match the expected hash gets flagged immediately. This turns "does this file look wrong" into a simple yes-or-no check.
Plugins and themes are trickier. Not everyone keeps the original source files handy. Pulling a matching version from the official repository still works the same way.
Diff it against your live copy. Differences jump out fast, even inside large files with thousands of lines.
This method catches what eyeballing misses every time. A single injected line at the bottom of a two-thousand-line file is nearly invisible to a human. A diff tool spots it in seconds, without fatigue or guesswork.
Version history helps too, when it's available. A site tracked in version control can show exactly which change introduced the problem. Most WordPress sites don't have that luxury. That's exactly why checksums and manual diffing matter so much.
This is slower than a quick scan. But it's far more thorough. When the goal is to remove malware from WordPress completely, that trade-off is worth making every time.
Testing before you bring the site back live
Cleaning the site isn't the finish line. You need proof it's actually clean before real visitors see it again. That proof shouldn't come from testing on your live domain.
Mistakes made there are visible to everyone, including search engines. A staging copy is the right place for this step instead.
Clone the cleaned site to staging. Keep it away from search engines and real traffic. Run a fresh scan against that copy, on its own.
Catch anything that still lights up before it costs you a second Google warning. That second warning is far harder to recover from than the first one.
Watch the staging site's outbound behaviour too, not just its files. Some malware calls out to remote servers to fetch fresh instructions. Monitoring network requests for a day or two can reveal a backdoor a file scan alone would miss.
Test every core user flow on staging, not just the homepage. Checkout pages, contact forms, and login screens can all carry separate injections. A site that looks clean on the surface can still fail this deeper pass.
Only move forward once the staging copy passes clean twice. That means two separate scans, not one hurried pass. Then the live site can safely return to normal operation. Rushing this step is exactly how sites get reinfected within days.
Common DIY mistakes that make things worse
Deleting files on sight is the biggest one. A file with a strange name might be a legitimate plugin file, not malware. Delete the wrong thing, and you break the site instead of fixing it.
Restoring from a backup feels safe. It often isn't. If the infection existed before that backup was taken, you've just reinstalled the malware.
Always confirm a backup's date against when the infection actually started. Use your log timeline as the reference point, not a guess.
Missing a second injection is another frequent trap. Attackers rarely leave just one door open. Clean the obvious payload, miss a smaller backdoor, and the site gets reinfected within a week.
Changing only the visible symptoms is the last one. Removing a spam redirect without finding how it got there fixes nothing long-term.
Ignoring file permissions is another quiet mistake. Loose permissions let an attacker back in even after the code is gone. Tightening them is a small step people skip, since it isn't dramatic like deleting a file.
Trusting a single free scanner's "all clear" is another. Free tools are useful as a first pass, not a final word. A green checkmark isn't proof the site is safe. Treating it that way is a mistake. It turns a shallow attempt to remove malware from WordPress into a job that only looks finished.
The goal isn't to remove malware from WordPress just once. It's to remove it, and actually keep it out for good.
Talking to customers and stakeholders during the clean-up
If the site is public-facing, silence makes things worse. Customers notice when a site goes down, or throws browser warnings. A short, honest status update beats letting people find out on their own.
Keep the message simple. Say the issue is known. Say it's actively being handled. Give a realistic sense of timing, without overpromising a specific hour.
You don't need to explain the technical details of the exploit. Most customers just want to know the site is being taken seriously.
And that someone competent is actually on it. That reassurance matters more than the technical specifics ever will.
Internal teams need updates too, not just customers. Whoever manages content or support should know what's happening. A confused editor logging in mid-cleanup can undo careful work without meaning to.
If customer data might have been exposed, that's a more serious conversation. It may carry legal obligations, depending on your location and industry. Get clarity on that early, rather than guessing under pressure later.
Once the site is confirmed clean and live again, send a brief follow-up message. It closes the loop cleanly, and shows the issue was taken seriously from start to finish.
What a complete clean-up actually looks like
A partial clean-up removes the symptom. A complete one removes the cause, and proves it's gone. Those look identical on the day you finish. They aren't the same outcome at all.
Done properly means every core file matches a known-good copy. Every plugin and theme is confirmed clean, or fully replaced from a trusted source.
The database has been checked for injected rows, not only the obvious ones sitting in plain sight. That check has to cover every table that accepts input, every time.
Done properly also means every password and every security key has been rotated. Every unrecognised admin account is gone for good. Nothing gets left "probably fine" out of convenience.
It also means you know exactly how the attacker got in. Not a guess. Not "probably an old plugin."
An actual identified entry point, confirmed from the logs, that's now genuinely closed. That's the difference between a clean-up and a temporary patch.
I've watched this same pattern repeat across more than 10,000 WordPress sites cleaned over the years. The clean itself is rarely the hard part of the job.
Across more than 573 businesses secured, the sites that stay clean share one thing. Someone treated the clean-up as complete, not just quick. That's part of why the client return rate sits around 96%. People come back once they see the work actually holds.
Proving it's genuinely finished is where most DIY attempts to remove malware from WordPress quietly fall short. Getting it right the first time is always cheaper than doing it twice.
Get help to remove malware from WordPress
Trying to remove malware from WordPress yourself is doable, but a single missed backdoor undoes the whole job. If you would rather hand it to a specialist, see my WordPress malware removal & security service. For an authoritative reference, read the official WordPress hardening guide.
Free security check
Worried your site is infected?
Get a free security check — I'll tell you if your WordPress site is compromised and exactly what it needs. No obligation.
Follow-up questions
People also ask
Security plugins help you detect and quarantine known malware, but they miss custom or well-hidden infections and they don’t fix the entry point. They’re a useful signal, not a complete clean-up.
Not if it’s done carefully. A proper clean-up preserves your posts, pages and media while replacing the compromised code around them.
It depends on how deep the infection goes. A single injected file is quick to handle. A compromise spread through the database, several plugins, and hidden admin accounts takes longer to trace properly. Rushing the process is worse than a slower, thorough one.
Yes, if the entry point wasn't actually closed. Cleaning removes what's there right now. It doesn't stop the same vulnerability from being used again. That's why finding the specific door the attacker used matters as much as the clean-up itself.
Not always. Most infections come through the website itself, not the hosting environment. On shared hosting, though, a neighbouring compromised site can sometimes spread sideways. It's worth asking your host directly whether that's a risk in your case.
You can still recover without one. It just means rebuilding core, plugins, and themes from fresh official downloads instead of a saved snapshot. The database needs a manual clean instead of a simple restore. It's more work, but a missing backup isn't a dead end.
Related
Take it further.
Keep reading