The first viewer question: cleaning up a website
As it always is on Office Hours, our audience was actively involved in the discussion through questions. One viewer asked about something many agencies face after a site is compromised and is something everyone should ask themselves after cleaning it.
How can you be sure that your site is completely clean after being hacked without just nuking it and starting over again?
Of course, the safest answer is to start over. However, is that always practical?
Client sites carry years of content, settings, and history. Not only that, but rebuilding from scratch is also expensive in itself. So, Thomas's answer focused on explaining how an infection keeps coming back and a few practical tips on how to handle such an issue.
Why does malicious code keep coming back?
When a reinfection happens, it's often due to something the attacker left behind rather than user error or bad luck. Even after cleaning the site, there are two things that Thomas mentioned which can cause malware to return: a self-healing infection and hidden admin users.
What's a self-healing infection?
As the name suggests, it's a virus that even after getting cleaned by anti-malware software, manages to rebuild itself. It sounds like something from a futuristic film, but it's much less complex.
As Thomasn explained it, such an infection is merely a set of components that are protecting each other. He gave an example with malicious code in the database (for example in the wp_options table) that watches if the attacker's fake plugin is still on the site. If not, the code recreates it. Thomas's team documented this kind of infection in a case study of a site that rebuilt itself from its own database. It can also work the other way around, as he further elaborated:
Now, if you go into the database and you pull out all the code from the database, but the plugin is still there, the plugin is going to regenerate the code in the database.
There can also be elements of the attack that landed in the server. Attackers can drop scripts into temporary directories, create cron jobs, or even start processes that run on the site's own system user. The process can watch for when a cleanup happens and simply replace the infected code when it's gone.
As Thomas explained, it's all about building persistency, and if you've ever watched a file that was removed after cleanup reappear almost immediately, this is probably why. This exact behavior was documented by Thomas's team in another case study that shows how the infection recreated its files at the end of the very page request in which they were deleted.
Why don't hidden admin users show up in the dashboard?
When you check for unknown users you go to the Users section in the WordPress dashboard, right? Attackers know that as well.
A hidden administrator account can, in fact, exist in the database without appearing in that list. Thomas mentioned he had seen a case where the site had been infected for months before it was discovered. The attackers had a hidden admin user and nobody noticed it until the site underwent thorough cleanup.
The Users screen builds its list by running a query, and malicious code can alter that query.
NinTechNet documented one such method to obfuscate a user from the query. By adjusting the pre_user_query, attackers can tamper with the query that retrieves the users. The account is still in the database; WordPress is just not allowed to show it. Thomas's team saw a similar approach in the first case study we linked above, where hooks on the user query, among others, hid the extra account and adjusted the user count to hide it.
In another case documented by Sucuri, a malicious plugin disguised as legitimate was used to filter the attacker's account out of the user list, while in a campaign reported by Monarx in early 2026, a malicious plugin was used to force the Users list to show only the logged-in admin and overwrote the total count to one.
This is why a simple look at the Users table is no longer sufficient, and this is why a thorough database check is necessary. Even then, if there is malicious code that will just recreate the account a second later, that's worth hunting down first, tying us back to the self-healing infection from earlier.
Can you just restore from a backup?
One of the first things everyone reaches for when they learn their site is infected is a backup restore. It feels like the safe choice, but the reality is that it will only work if the backup is from before the infection. Thomas's own take on doing this offered a different perspective:
People say, well, what I do when I get an infected site is I just restore from a known good backup. Really? Because, like I said, we're seeing more and more sites that were infected months and months ago.
If your backup is from after the site was hacked, restoring it does nothing to clean it. And if you go too far back, you may also lose months of legitimate changes.
Backups still have a use, though. They should be treated as more of a starting point than anything else. Of course, if you have one you are certain is clean, restore away. If you don't, though, you can use your backups as a means of finding out when the site was infected. We suggest using an isolated environment where the infection can't cause any damage.
If you do find an old backup that's clean, there is one more thing to keep in mind, other than that you may lose months of progress as we mentioned above. One user during the livestream shared that they had restored a website that had been offline for a month. However, they had forgotten to update core and plugins after the restore, and the site got hacked the next day.
So, if you do restore, ensure the backup is clean and that all software your site relies on is up to date.
Which parts of a WordPress install are safe to replace?
The good news is that not every single file needs to be treated with the same distrust. Some parts of WordPress you can flat-out delete and replace with fresh copies, while others deserve even greater scrutiny.
We've put together the table below with Thomas's advice to illustrate what's safe to remove and what should be looked at more closely, including a couple of precautions.
Location | What to do |
wp-admin and wp-includes | These two directories should contain only what WordPress itself ships. Delete them and replace them with fresh copies of the same WordPress version your site runs. |
wp-config.php | This file should be hand-reviewed line by line for code that doesn't belong. It holds important site information (like database credentials) so don't blindly overwrite it. |
.htaccess | Similar to the above, review line by line for any injected redirects. |
wp-content/plugins and wp-content/themes | Delete what you don't use and reinstall the rest from an official source. Back up any customizations first, such as a child theme or edited plugin files, and review them line by line before putting them back. |
wp-content/uploads | This is a directory for images and documents. Look for any PHP files that don't belong here. |
wp-content/mu-plugins | Check for anything you didn't create. The plugins here load automatically and can't be switched off from the Plugins screen. |
Additionally, if you use WP-CLI you can run wp core verify-checksums to compare your core files against official checksums from WordPress.org. If there are any discrepancies (such as missing, changed, or errant files) they'll show up. It doesn't load WordPress while it checks either, so compromised code can't interfere with it.
However, when it comes to things in the wp-content directory in general, Thomas was adamant that everything must be fully scanned. Attackers hide fake plugins and web shells in there and, as he said, some are built to look legitimate:
I don't care how good they look. And a lot of them have super easy ways to hide code, hide it from most scanners.
That's also why the table above favors reinstalling from official sources over hoping a scan catches everything.
What to check before calling a website clean
The reality is that the more complex attacks become, the more complex cleanups are as well. To that end, here's a list of things to check after your typical cleanup processes are done. Again, this advice is primarily for WordPress, but many of these checks can be applied to other platforms too.
Admin users: As you saw earlier, relying solely on the Users screen is inadvisable. Look at the users table and user capabilities in the database directly instead. Confirm that every administrator is someone you recognize. And, while you are at it, open each profile and review the application passwords listed there; revoke any you don't recognize.
Cron jobs and scheduled tasks: Check the WordPress scheduled events (wp cron event list, for example) and look for anything you didn't create. Also look at the server-level cron jobs, as attackers can create entries there, too, or ask your host to check for you.
Files outside the WordPress directories: One thing Thomas noted is that attackers often park scripts in temporary directories (such as /tmp and /var/tmp) because those locations must be writable for the system to function. Those are usually hidden as well, making them that much sneakier to clean up.
A site that passes all four of these checks is in a much better position than one that has only been scanned. But "scanned" covers several different processes, which leads us to the next section of our blog.
The second viewer question: What does each layer of security protect?
When it comes to site security, no single tool covers every possible risk. That's why website security is instead made up of many layers that each guard something specific. This makes it easier to keep track of things and makes it clear what tools you need to fill in gaps in your defenses.
The question of how those layers fit together came after a viewer had just heard Thomas explain why scanning for malware from inside a plugin isn't ideal. It's not ideal because the plugin shares the same privileges and file system as any infected code. Because of that, the viewer was curious how Thomas's outside approach fits with what a host already does:
How does that interface with what hosting security or, you know, the typical kinds of security that hosting companies have on servers?
In the table below you'll see what each layer of security protects and that they don't really overlap as much as people tend to assume.
Layer | Where it's strongest | What it can miss |
Your host | Server-level defense: the operating system, web server software and, on some plans, a WAF | Anything already inside the application, such as a rogue plugin, a hidden admin user, or code stored in the database |
A security plugin | Spotting known malware and hardening logins with features such as 2FA and passkeys | Stolen admin session cookies (which bypass 2FA), files an attacker adds to its trusted list, and server-level leftovers such as system cron jobs and scripts in temp directories |
Virtual patching | Blocking exploit attempts against known vulnerabilities in the plugins you have installed | Backdoors and rogue admins already on the site, and flaws that haven't been reported yet |
Monitoring with automated cleanup | Watching traffic, files, databases and logs for malicious activity, then removing what it finds and notifying you | Floods of traffic meant to knock a site offline, which an edge firewall handles, and compromises deeper than the site, such as root-level access to the server |
As you can see, each layer has its own specialty. Of course, there are some plugins that try to handle everything, but we, as well as Nathan and Thomas, strongly advise against them. This separation of the workload ensures systems that were specifically built for a particular protection task handle it much more efficiently and better.
With that said, let's elaborate on each layer and see exactly how they handle threats.
What does the host protect?
Thomas's answer didn't focus on one specific aspect of malware protection, like file scanning, and was instead more of a job description for the host:
Hosting companies for the most part, unless you get into managed plans and so forth, their job is to protect the server.
"The server" means the operating system, the web server software, and the core files that keep them running. This is what protection at this layer typically looks like:
Network firewalls and DDoS mitigation: Blocking hostile traffic by its source, type, and volume, so a flood of bot requests never ties up your server.
All of these are very valuable for the protection of a server. However, you can see that a WAF won't bat an eye at what's already installed, nor will a malware scan detect a rogue admin user. According to Thomas, server defenses typically stop short of those things and don't look at the application layer where WordPress, its plugins, and its database live.
Because of that, Thomas's earlier caveat regarding managed hosting plans matters here; those plans do go further. Hosting.com's Managed hosting for WordPress, for example, puts a Cloudflare Enterprise WAF in front of your site, adds Imunify360 at the server level, and includes continuous malware and file-integrity scanning with automated cleanup.
Of course, things like that help but the manual checking from the previous section is still vital.
What can a security plugin do?
Prior to the stream, another viewer asked what security plugins Thomas recommends for WordPress. He named two he likes and his reasoning was entirely practical: Kadence Security and Patchstack. Here's what each one does:
Kadence Security focuses on locking down access to your site with 2FA, passkeys, brute-force protection, and a security dashboard. The Pro version also includes vulnerability patching from Patchstack.
Patchstack matches the plugins, themes, and core of your site against a vulnerability database and notifies you when one is affected. The free version stops at notifications, but the paid plans add virtual patches that block exploit attempts.
He likes them because they are both easy on the resources but highly effective. One hardens how people get in and the other keeps watch over what you have installed. As you can see, neither is built primarily around malware scanning.
Feature-heavy plugins that bundle scanning, firewalling and more can strain server resources. It's best to avoid such plugins if your server already offers robust defenses.
What does virtual patching cover?
Virtual patching, the way Thomas described it, is like a firewall that prevents a plugin from being vulnerable.
It blocks attempts to exploit a flaw in a plugin, even before you have updated it. Good implementations of virtual patching inventory the plugins on your site and only apply protections for the ones you have. Patchstack, described above, is one example of this approach.
It's vital to remember, though, that such a plugin battles exploits and doesn't remove infections; it won't clean up a compromised one.
What does monitoring with automated cleanup add?
This layer works a bit differently. It watches the site itself instead of relying on plugin scans. Services in this category typically monitor traffic, files, the database, and logs for malicious activity.
They flag suspicious events, such as an admin login followed immediately by a new admin user or a new plugin appearing on the file system. Some go further than alerting, though: they remediate first, then notify you, and some also analyze logs to work out how the compromise happened. Knowing the entry point is critical to a proper cleanup.
There is a limit to its reach, though. It covers the site and its database, not the whole server. A compromise at the operating-system level is a different problem that another layer handles, as we described earlier. The same applies to a traffic flood meant to destabilize the site. Our comparison of Cloudflare's Under Attack Mode and website monitoring describes how those two layers divide the work.
Why no single layer catches everything
Each layer of protection performs a specific task.
Imagine one football player trying to play all roles on the field. They would get overwhelmed and do a subpar job. By specializing, the different layers of security ensure that each is an expert in a certain method of protection, and layered they create a solid shield for your website.
A verified cleanup checks all of these layers, which is why the checklist from earlier goes beyond running a simple scan.
How do you keep your site clean afterward?
Cleaning a site is one side of the coin, and the other is primarily good habits. Thomas explained that the old monthly maintenance rhythm is no longer enough:
It's now become critical that you're doing plugin, core, theme updates, probably two or three times a day.
Keeping your site secure is more vital than ever now. To help you with this, we've put together a short routine for you:
Rotate credentials after any incident. That includes hosting, FTP or SSH, database, and site admin passwords. Do it only once you have confirmed no files are regenerating, since some malware captures passwords as they are reset.
This checklist will help you catch most problems while they are still small. It also shouldn't add too much work to your weekly maintenance.
If you are curious what's built on our side, take a look at how security works on hosting.com's Managed hosting for WordPress plans. Alternatively, join us every Thursday at 2 p.m. ET for Office Hours where you can ask any questions related to WordPress, security, agency work, AI, or hosting in general, and get answers live from Nathan and our Agency Success community.
FAQ
Can my host's malware scan tell me my site is clean?
Not on its own. A "no threats found" result only means nothing matched what the scanner knows how to look for, in the places it looks. Ask your host what its scan covers: which directories, how often, and whether it examines the database. Then treat the result as one input alongside the manual checks above.
What should I do if I can't find the source of the reinfection?
Start by asking your host to check for running processes and server-level cron jobs under your account. Once you've confirmed nothing is regenerating, rotate every credential, since some malware captures new passwords as they are set.
That includes your database password in wp-config.php and the WordPress security keys, which logs out all existing sessions and invalidates stolen cookies. If several sites share one hosting account, treat all of them as suspect until each has been checked.
As a last resort, you can move a fully verified set of files to a fresh account.
How often should I check admin users and scheduled tasks?
There is no official rule, but a reasonable approach is to check weekly for the first month after an incident and monthly after that. For agencies, adding it to your regular maintenance checklist keeps it from being forgotten.