WordPress

Hacked WordPress site: attack surface, incident response and what really changes

Hacked WordPress site: where automated attacks get in, how to handle the incident technically, and why fewer components matter more than a security plugin.

Fabio Folgori5 min read

Old rusty padlock on a wooden door
Photo by Arkadiusz Gąsiorowski on Unsplash

Most compromised WordPress sites I have seen were not chosen by someone. They were found by a scanner. Attacks on WordPress are almost always automated: bots mass-testing a vulnerability just disclosed in a popular plugin, or credentials stolen elsewhere. Understanding this changes how you respond and, above all, how you prevent it.

Where they get in

WordPress core is mature and patched quickly. The risk is almost always elsewhere.

  • Vulnerable plugins and themes: most vulnerabilities reported in the ecosystem concern third-party components. Unchecked file uploads, AJAX or REST endpoints without permission checks, SQL injection in search filters, privilege escalation from registered user to administrator.
  • Abandoned components: plugins removed from the official repository but still active on thousands of sites. Nobody will ever ship the fix.
  • "Nulled" themes and plugins: pirated copies of commercial products, often distributed with a backdoor already included.
  • Credentials: reused passwords, shared admin accounts, no second factor. wp-login.php and xmlrpc.php are hammered constantly.
  • Hosting: overly loose file permissions, unsupported PHP versions, several sites under the same system user, so compromising one infects the others.

The key point is the exposure window: between a vulnerability being disclosed and the site actually being updated, hours, days or weeks go by. Automated scanners start exploiting it quickly. With thirty active plugins, those windows overlap almost constantly.

Recognising the compromise

Visible signs (redirects to other sites, indexed spam pages, Google Safe Browsing warnings) come late. Technical ones come earlier:

  • unknown administrator users in wp_users, or capabilities altered in wp_usermeta;
  • PHP files in wp-content/uploads, which should contain none;
  • core files that do not match the official checksums (verified with WP-CLI);
  • must-use plugins or drop-ins nobody installed;
  • options in wp_options with obfuscated code, unknown cron jobs;
  • spikes of unusual POST requests in the server logs.

Spam injected only for Googlebot (cloaking) is a classic: the site looks normal to visitors, but Search Console shows pages in languages or topics that are not yours.

Incident response, in order

  1. Contain: maintenance mode or traffic block, without deleting anything. The compromised files are also the evidence.
  2. Snapshot: a full copy of files, database and logs as they are. It is how you understand what happened and since when.
  3. Rotate every credential: WordPress admins, database, FTP/SFTP, hosting panel, API keys stored in the site. Regenerate the salts and keys in wp-config.php to invalidate active sessions.
  4. Find the vector: match file modification dates with access logs, check which components had known vulnerabilities in that period. Without this step, the clean-up is temporary.
  5. Rebuild, don't scrub: core, themes and plugins are reinstalled from official sources, never "cleaned" by hand. The database is reviewed table by table. Uploads are filtered by file type.
  6. Close the hole: update or remove the vulnerable component. If it is abandoned, replace it.
  7. Bring it back online and request a review in Search Console if the site was flagged.
  8. Assess GDPR obligations if personal data is involved.

The backup is most useful at this stage: not to roll back blindly, but to compare a healthy state with the compromised one.

Prevention: fewer components, not more layers

The instinctive response to an attack is to add a security plugin. It helps on some fronts, but it is more code inside the same application you are trying to protect. The measures that really count are structural:

  • cut plugins down to the essential ones, chosen for active maintenance and vulnerability history;
  • timely, tested updates on a staging environment, with a procedure rather than "whenever";
  • two-factor authentication for every administrator, minimal roles for everyone else;
  • DISALLOW_FILE_EDIT and correct file permissions, so a compromised account cannot rewrite code from the dashboard;
  • no executable PHP in uploads, enforced at server level;
  • a WAF in front of the site, blocking known exploits before they reach WordPress;
  • file integrity monitoring and alerts on new administrators.

How I set this work up over time is covered in WordPress maintenance: the real cost over time.

What changes with a static site

A site generated in advance and served from a CDN, like the ones I build with Nuxt and Netlify, runs no server-side code on each visit, exposes no database and has no public login panel. The most common class of attacks on WordPress simply has no target.

The surface shifts: what remains to protect is the GitHub account, the hosting provider account and the domain registrar. Three accounts with two-factor authentication instead of dozens of components to update. And every change to the site goes through a tracked commit, so an unauthorised change is visible and can be reverted in a minute.

My take

I love WordPress, but today it is the most attacked target on the web precisely because it is everywhere, and the way it is used (dozens of plugins, themes that do everything) multiplies the entry points. I have cleaned up enough sites to know the problem is rarely a mistake by whoever runs them: it is an architecture where everything is tied to everything and one neglected component is enough to fall.

When a project really needs WordPress, I keep it lean and look after it with a procedure. When it does not, I suggest moving to a static architecture: it is the most effective security measure I know.

Why work with me

I have been programming since 1999, delivered more than 300 projects and work as an external developer with about 30 agencies, from Rome and remotely. I handle WordPress incidents methodically: containment, vector analysis, clean rebuild, then a plan so it does not happen again.

If your site has been compromised, or you fear it has, get in touch: first we find out how they got in, then we decide how to get it back on its feet. The service is in WordPress maintenance.

Frequently asked questions

Only if the backup predates the compromise and the entry point is closed. Many attacks lie dormant for weeks: restoring without knowing how they got in means reopening the same door.

It reduces some risks (brute force, known malware signatures), but it runs inside the same WordPress it is supposed to protect. If the vulnerable code is a plugin, the security plugin often notices afterwards.

If the site processes personal data and there has been a breach, the GDPR may require notifying the supervisory authority within 72 hours and, in some cases, the people affected. It should be assessed straight away with whoever handles privacy.

It can, but the surface is much smaller: no PHP running on every request, no exposed database, no public login. What remains to protect are the GitHub, hosting provider and domain accounts, with two-factor authentication.

  • #hacked website
  • #wordpress security
  • #malware
  • #incident response
  • #maintenance

More articles

// Contact

A project, a problem or just a question?

Agency, business or professional: choose how you'd rather talk to me. I reply within one working day, no strings attached.