Hacked WordPress site: how I secured it and made it faster in a few hours
A warning from Search Console, a blank site and the decision to shut WordPress down instead of fixing it. The story of the intervention and what changes with a static build.
Davide Ruggeri
· Updated October 15, 2026Today one of the sites I manage was attacked. A few hours later it was back online, with no database, no PHP running and faster than before. Not because I was good at fixing it: because I got rid of the thing that had broken.
The attack: an email from Google Search Console and a blank site
The warning came in an email from Google Search Console: a user had been added to the property. It wasn’t me.
Alarmed, I open the site: blank page.
Why I didn’t investigate the causes of the attack
I didn’t spend a second working out who had got in, from where, or what they were trying to do. Analysis is done calmly, on a frozen copy, once the client’s site is already working again. My only thought was: I have to act now.
The operational question was just one: which piece got breached, and do I still need it?
The weak spot: a WordPress instance behind the proxy
This client’s stack is the one I described in From WordPress to a modern stack: a Node server running SvelteKit in front, intercepting every request, and behind it the original WordPress installation, which keeps serving the routes created before I came in.
It’s an architecture that works very well for migrating without trauma. But it has one feature that’s convenient to forget: as long as the origin stays on, its attack surface stays on too. PHP running, a database, inherited plugins, a reachable login page. The proxy moves routes, it doesn’t make what’s behind it disappear.
And that “behind” was barely needed anymore. I had already migrated all the dynamic parts to SvelteKit: the proxied part was just content. Pages that change a few times a year, served by a live application running twenty-four hours a day to say the same things over and over.
I’d been wondering for a while whether we really needed to keep WordPress running down there. The attack took away my excuse to put it off.
Three goals, in this order
- Deal with the attack on the spot.
- Hardening: I don’t want that surface anymore.
- Maximum speed.
The interesting thing is that a single move satisfies all three.
From dynamic WordPress to a static build: what I did
I rebuilt the WordPress instance locally, generated the full static export (content, redirects, sitemap) and served that output from a container that does nothing but return files. On the proxy, all it took was repointing the upstream: same routes, same URLs, same look. I changed the engine, not the bodywork.
What runs on that part of the site now: no PHP, no database, no admin area, no plugins. Files on disk, behind a proxy I wrote myself.
What you gain with a static WordPress site
- The attack surface shrinks to the web server. There are no credentials to guess and no plugin vulnerabilities to wait for.
- The response time is the time it takes to read a file, which is the physical limit of the problem.
- The backup is a folder, and restoring it means copying it.
- There’s no longer a database to update, monitor and back up for content that doesn’t change.
What you give up, because you do give something up
Anyone selling you a solution with no downsides is selling, not explaining.
With static, the features that lived in the runtime go away too: forms have to be moved to an external endpoint, internal search and comments have to be rethought or dropped, and every publication needs a regeneration step instead of being immediate. If a site needs members’ areas, shopping carts or content that changes on its own, this path isn’t for it.
The point is that most business sites don’t need any of that. They need to be fast, to be found and not to go down.
What to do after an attack, even if you postpone the analysis
Giving up on investigating the causes is a legitimate choice. Giving up on these things isn’t, and it’s the part usually missing from stories like this one:
- Immediately remove the account added in Search Console and review all the users on the property. Access to webmaster tools is used to manipulate indexing, and that damage outlives the restoration of the site.
- Regenerate credentials and keys, and check the admin users left in the database before archiving it.
- Check the export. If you generate the static site from a compromised instance, you risk freezing the injection into the files too. Before publishing, look for external scripts, iframes and hidden links that shouldn’t be in the output.
- Keep a copy of the attacked instance. A postponed analysis is postponed, not cancelled.
WordPress as a static site builder: the only use I accept on a professional site
I almost never use WordPress to build professional sites, and I’ve written about the reasons elsewhere. This, though, is one of the rare cases where I find it acceptable, even sensible: WordPress as a tool for composing content, whose end product is a set of static files, and not as an application exposed to the public.
Turned around like this, the cost-benefit balance changes. You keep an editor clients know and an archive of content already written, and you throw away the part that causes the problems: the exposed runtime, the database, the plugins running code on every visit, the updates to chase forever.
Before, it was a house with ten doors, each with a lock to maintain. Now it’s a wall with one window onto the world, and I control the window.
If you have a WordPress site that worries you
If you’re wondering what would happen to your site on a day like this one, tell me about it. I’ll tell you which part of your site really needs to be a live application and which can become a file instead, how long it would take and what would change in response times.