"We changed the password. It got hacked again anyway."
That's how most of these conversations start.
A client running a WordPress store came to us after being hacked repeatedly. Each time, they did what most site owners are told to do: change the admin password, maybe change the hosting password too, and hope it sticks. Each time, within weeks, something was wrong again.
By the time they reached us, they weren't looking for another password reset. They wanted to know why it kept happening — and whether their previous developer had simply missed something, or whether the site itself was fundamentally compromised in a way a password change could never fix.
It was the second one.
What we found
The short version: the site had been compromised through a vulnerable plugin, and the attacker used that access to plant a backdoor — a hidden file that lets them back into the site whenever they want, completely independent of any WordPress login. Password resets don't touch a backdoor like this, because the attacker was never relying on the password in the first place.
Once we started digging, we found the plugin responsible for the original entry point had itself been removed — not by the client, and not by us. Attackers frequently do this once they've established a backdoor: remove the vulnerable plugin that let them in, so a site owner (or a less thorough investigator) looking at the installed plugin list sees nothing unusual, and the original point of entry disappears from view entirely.
We also found something the client hadn't noticed at all: a page on their live site promoting an online casino, styled to blend in perfectly with their actual theme and branding — same header, same footer, same fonts. It wasn't linked from anywhere in their navigation, so a normal visitor (or the client themselves) would never stumble across it. It existed purely to be indexed by search engines. Digging into the database turned up several more posts just like it, created and quietly deleted over the preceding weeks.
This is a far more common outcome than most business owners expect. A compromised WordPress site isn't just a security problem — it's a monetisable asset to whoever controls it. Injecting spam content that targets high-value search terms (gambling, pharmaceuticals, replica goods, and similar categories are the classic examples) lets an attacker piggyback on a legitimate site's existing search engine trust, and often builds backlinks that benefit other sites the same attacker controls. Your store's hard-earned domain reputation becomes someone else's SEO asset, quietly, in the background, while everything looks normal on the surface.
How we found it
None of this was visible from the WordPress admin dashboard. That's the point of a well-hidden backdoor — it's designed not to be visible from the places a normal site owner would look.
Our process combined a few layers, deliberately, because no single check catches everything:
Offline malware scanning. We pulled a full local copy of the site's files and ran it through signature-based scanning tools (ClamAV and Linux Malware Detect), looking for known-bad code patterns. This is a useful first pass, but it only catches malware that matches an existing signature — it won't catch something custom-written or well obfuscated.
Manual pattern review. We searched the codebase for common backdoor indicators — code that decodes and executes hidden payloads, unusual file-execution calls, and files sitting in locations that should never contain executable code (more on that below). A simplified, defanged example of the kind of pattern we look for:
php
// Illustrative only — payload removedeval(base64_decode("<hidden_payload_removed>"));
This pattern — decoding a chunk of scrambled text and then executing it as code — is one of the most common ways attackers hide what a backdoor actually does from a casual glance at the file. On its own, spotting this pattern isn't proof of compromise (some legitimate plugins misuse base64 for harmless reasons), which is why automated pattern-matching always needs a human reviewing the context, not just a keyword search.
Checking where files shouldn't exist. WordPress's uploads folder is meant to hold images, PDFs, and similar media — never executable PHP. Finding a .php file sitting in that folder is one of the strongest single signals of compromise there is, because there's essentially no legitimate reason for it to be there.
Database investigation. The spam content wasn't sitting in an obvious "recent posts" list — it had already been partially cleaned up and trashed. We queried the database directly for post history, publication patterns, and associated media, which is how we uncovered the fuller scope of what had been published and quietly removed over time.
Checksum verification. WordPress core files should match, byte-for-byte, what's published on WordPress.org for that exact version. Comparing the client's live files against the official release is one of the most reliable ways to catch a modified core file that a signature scanner might miss entirely.
This pattern — decoding a chunk of scrambled text and then executing it as code — is one of the most common ways attackers hide what a backdoor actually does from a casual glance at the file. On its own, spotting this pattern isn't proof of compromise (some legitimate plugins misuse base64 for harmless reasons), which is why automated pattern-matching always needs a human reviewing the context, not just a keyword search.
Checking where files shouldn't exist. WordPress's uploads folder is meant to hold images, PDFs, and similar media — never executable PHP. Finding a .php file sitting in that folder is one of the strongest single signals of compromise there is, because there's essentially no legitimate reason for it to be there.
Database investigation. The spam content wasn't sitting in an obvious "recent posts" list — it had already been partially cleaned up and trashed. We queried the database directly for post history, publication patterns, and associated media, which is how we uncovered the fuller scope of what had been published and quietly removed over time.
Checksum verification. WordPress core files should match, byte-for-byte, what's published on WordPress.org for that exact version. Comparing the client's live files against the official release is one of the most reliable ways to catch a modified core file that a signature scanner might miss entirely.
Why this happens
It's worth being clear that this isn't really about one careless plugin choice. It's a pattern we see constantly:
A site accumulates plugins over years — some actively used, some installed once for a specific task and then forgotten. Every one of those plugins is a piece of code with the same level of access as WordPress core itself. If any one of them has a vulnerability, and it usually only takes one, that's a way in.
Once an attacker is in, the incentive isn't just to deface the site or steal data — it's often to quietly monetise the access itself, for as long as possible, without being noticed. That means the goal shifts from "cause visible damage" to "stay hidden and keep working in the background." A backdoor that survives password resets, combined with spam content that isn't linked anywhere visible, is a textbook version of exactly that strategy.
And critically: removing the malware you can see doesn't remove the way they got in. If the entry point isn't identified and closed, cleaning up the symptoms just buys time until the same access is used again.
How to prevent it
A few things make the biggest difference, in rough order of impact:
Keep plugins to the minimum you actually use, and keep every one of them updated. An unused, outdated plugin is pure risk with zero benefit. If you're not sure whether something's still needed, that's worth checking rather than assuming.
Never assume a password reset fixes a compromise. If a site has been hacked more than once, or keeps showing unexplained changes, the working assumption should be file-level compromise, not credential theft, until proven otherwise.
Monitor file integrity continuously, not just when something looks wrong. By the time a site owner notices something's off, a backdoor may have been sitting there for months. Regular, automated scanning against known-good checksums and common malicious code patterns catches this early — before it becomes a search-engine penalty, a data breach, or a customer trust problem.
Take backups seriously, and test that they actually restore. A clean, verified backup from before the compromise is often the fastest real path back to a trustworthy site.
Get a proper audit after any suspected compromise, not just a quick clean-up. If the entry point isn't found and closed, the same vulnerability is still sitting there.
How Apaxon can help
This is exactly the kind of work we do for clients: full forensic investigation of a compromised WordPress site, identifying the actual root cause rather than just symptoms, complete cleanup and rebuild where needed, and credential rotation across every system that touches the site.
For ongoing protection, we've built Apaxon Shield, a monitoring service designed specifically around the patterns described in this post: continuous scanning of core, plugin, theme, and upload files against known-good checksums, detection of common backdoor code patterns, and immediate alerts the moment something changes that shouldn't have. It's built to catch exactly the kind of quiet, persistent compromise that a one-off scan or a password reset will always miss.
If your site has been hacked more than once, or something about it just feels off, that instinct is usually worth listening to. Get in touch — we'll find out what's actually going on.
Get the latest IT insights
Expert tips, infrastructure news, and product updates — delivered weekly.