The old taamneh.com looked completely normal when I visited it. The WordPress blog loaded, the familiar pages were there, and cPanel had been kept up to date. From the administrator's point of view, there was no obvious emergency.

The problem was that other visitors were not necessarily seeing what I was seeing.

During an unrelated check with Codex, we noticed that one URL behaved as if it were redirecting somewhere else. A broader inspection showed that the site had been compromised and was serving gambling and other unwanted content selectively. Direct visits could still receive the legitimate blog, while requests arriving under different conditions could be sent elsewhere.

That was the most unsettling part of the incident: the website had not simply been defaced. It had been made to lie to its owner.

A compromise designed to stay unnoticed

Google calls this behavior cloaking: presenting different content to different users or to search engines. Its documentation notes that hacked sites commonly use cloaking to make the compromise harder for the owner to detect. Google also documents malicious redirects that depend on the referrer, user agent, or device—for example, a redirect that appears when a visitor arrives from search results but not when the same URL is opened directly.

That description was uncomfortably close to what happened here.

The redirect was not the whole compromise. A deeper review found that .htaccess had been modified. We also found extensive duplication inside the hosting account: 209 additional MySQL users, 209 database copies and 209 WordPress instances. The repetition suggested automation and multiple layers of persistence rather than a single changed file.

I cannot honestly identify the original entry point from the evidence that remained. It may have been a vulnerable plugin or theme, a WordPress flaw, compromised credentials, or a combination of weaknesses. The hosting control panel being current did not prove that the application above it—or the credentials used to reach it—was safe.

What I can say with confidence is what we observed: conditional redirects, a compromised server configuration file, unexpected accounts and a large number of duplicated application and database artifacts. Anything more specific would require logs and forensic evidence that were not available after cleanup.

Why this incident was different

This was the third time the WordPress site had been compromised. Earlier incidents could be treated as repair work: find the vulnerable component, update the installation, remove the malicious files and continue.

This time, that approach no longer felt defensible.

When an attacker has modified one file, cleaning that file may be enough only if the investigation proves that access stopped there. When the same account contains hundreds of unexpected users, databases and application copies, the question changes from Which file is malicious? to What evidence do I have that anything in this environment is still trustworthy?

That is a much harder standard.

Malware frequently establishes more than one way back in. A visible redirect can be replaced after removal by a backdoor in a PHP file, a scheduled task, a database payload, a stolen control-panel session or another modified configuration file. Cleaning only the symptom risks preserving the mechanism that recreates it.

With help from the hosting provider's support team, I removed the compromised environment and treated the account as a clean-slate recovery rather than an in-place repair. That decision was easier because the blog was old, contained no transactional or customer data, and the writing could be exported from the original WordPress content without preserving the executable application around it.

As far as I could determine from the checks available at the time, the unwanted pages were removed before Google began indexing them. That was fortunate, but it did not make the compromise itself any less serious.

Sometimes an incident does not create a new architectural argument. It simply pushes an existing argument past the point where it can be ignored.

This is common, but exact comparisons are difficult

There is no reliable public count of WordPress sites compromised in precisely this way. Security vendors see only the sites and traffic inside their own products, infections are classified differently, and many owners never discover or disclose an incident. It would be misleading to take one vendor's telemetry and call it a global compromise rate.

The available data still shows the scale of the problem.

In its 2024 WordPress security report, Wordfence reported seeing just under one million distinct sites infected with malware during the year, with roughly 325,000 to 350,000 infected sites observed on any given day. The company explicitly cautions that many owners install Wordfence only after an infection, so this is telemetry from its ecosystem, not a census of the web.

The same report recorded 8,223 disclosed WordPress ecosystem vulnerabilities in 2024. Wordfence attributed 96% of those disclosures to plugins and reported that approximately 35% remained unpatched in 2025. It also noted that hosting-account credential compromise was a frequent source of intrusion in cases handled by its response teams.

Those distinctions matter. “WordPress was hacked” does not automatically mean WordPress core was the vulnerable component. A WordPress installation is an operational system made of core, plugins, themes, PHP, the web server, a database, administrator accounts, hosting credentials and years of accumulated configuration. Keeping only one layer current does not secure the whole chain.

WordPress's own hardening guidance describes security as risk reduction and containment rather than a promise that a system cannot be compromised. It recommends current software, trusted sources, limited access and containment controls. Those are sound practices. They also require continuous ownership.

For a site whose main job is to publish text, I was no longer receiving enough value from that operational burden.

What AI changed in the investigation

AI did not magically secure the site, and it did not replace the hosting provider or produce a courtroom-grade forensic conclusion. Its value was more practical: it changed the speed and breadth of the questions we could ask.

Instead of checking only whether the homepage loaded, we could inspect the site as an external system:

  • compare direct requests with requests using different paths and headers;
  • follow redirect chains instead of trusting the page rendered in my browser;
  • enumerate unexpected files, WordPress copies, databases and users;
  • inspect .htaccess rules and identify behavior that did not belong there;
  • turn scattered observations into a remediation checklist;
  • verify the replacement site from both the filesystem and the public internet.

The useful shift was from “Does the site look fine?” to “Can I produce evidence that every important path behaves as expected?”

This is where AI can improve small-site security. Most personal sites do not have a security operations team. They are checked occasionally, usually by the same person who built them, from the same browser, network and authenticated sessions. An assistant can cheaply vary those conditions, correlate findings and keep looking after the first visible symptom has been removed.

But AI introduces its own failure mode: plausible certainty. It can suggest a likely attack path without enough evidence, misread obfuscated code or recommend destructive cleanup commands. The right role is an accelerator for inspection and verification, with a human retaining judgment and the hosting provider controlling the infrastructure it owns.

The replacement has a smaller job

The new taamneh.com does not run WordPress, PHP, a database or a public administration interface. I write Markdown locally, generate a static site and deploy the resulting files through Git to cPanel.

The architecture changed from this:

Internet
  → web server
  → PHP runtime
  → WordPress core
  → themes and plugins
  → database
  → public login and administration surface

to this:

Local Markdown
  → validated static build
  → Git deployment over SSH
  → HTML, CSS and static assets
  → web server

Static does not mean invulnerable. The hosting account, SSH key, DNS, local computer and deployment process still require protection. A compromised cPanel account could still replace static files. The difference is that production no longer executes an application stack whose components continuously accept input, query a database and expose an administrative interface.

The security model is now easier to explain, inspect, reproduce and recover:

  • source and generated output are version-controlled;
  • production does not need WordPress administrator credentials;
  • the server does not need Node.js or a build toolchain;
  • deployments are accepted only through a dedicated SSH key;
  • every release receives a deterministic fingerprint;
  • an automated check confirms that the public site serves that exact build;
  • rollback is a normal Git operation, not a database restoration exercise.

That smaller system fits the actual purpose of the site.

What I would do differently now

The biggest lesson is not “never use WordPress.” WordPress remains a reasonable choice when its editing experience, ecosystem and multi-user features justify the operational cost. The lesson is to make that cost explicit.

If I were responsible for another WordPress installation, I would treat it as an application rather than a collection of pages:

  1. Maintain an inventory of core, themes and plugins, and remove everything unused.
  2. Separate hosting, WordPress, database and deployment credentials; rotate them after any compromise.
  3. Monitor the site from outside the normal administrator browser and vary device, referrer and user agent.
  4. Alert on new administrator accounts, database users, files, scheduled tasks and configuration changes.
  5. Keep known-clean, offline backups and test full restoration.
  6. After a serious compromise, preserve evidence before cleanup and assume there may be more than one persistence mechanism.
  7. Define in advance when repair is no longer credible and a clean rebuild becomes the safer option.

Google's current spam policies explicitly describe hacked content, cloaking and conditional redirects of the kind involved here. Its older but still technically relevant guidance also points directly to modified .htaccess rules as a mechanism for referrer-dependent redirects. These are not exotic edge cases. They are established techniques designed to exploit the gap between what an owner checks and what other visitors receive.

The new site exists because that gap became impossible to dismiss. Losing trust in the old runtime was unpleasant, but it forced a better question: what is the smallest system that can do this job well?

For taamneh.com, the answer is not a more heavily defended CMS. It is no CMS at all.

← Back to writing