Incident runbook · Advanced · half a day
How to clean up a hacked website — Incident Response for One Website, Start to Verified
Cleaning a live site while the intruder still holds a valid credential is unpaid work — contain first, then eradicate, then prove it with something you can show someone.
The short answer
Contain before you clean: put the site into maintenance mode and invalidate every credential in one pass, because every hour spent removing files while the intruder still has a working login is an hour you will repeat.
Then work in the order that makes the fix stick. Find the intrusion window from timestamps and the access log, restore from behind it, patch the entry point before the site goes back up, sweep the places backdoors actually live, and only then rebuild your standing with the search engines. Half a day, done properly, beats three days of recurrences.
By the HostingFast team · Reviewed 24 August 2026
Advanced
Assumed level
5
Stages to verified
Free
Support cost
Proven
Proven on our platform
This is the advanced page in the family, and it assumes SSH, WP-CLI and comfort reading a log. All three are available on every shared tier here.
Before you touch anything, take a copy of the compromised state. You will want the evidence later — to find the entry point, and to answer questions about what was exposed.
Containment comes before cleaning
Maintenance mode first, so the site stops serving injected content to visitors and stops accepting writes while you work. Then invalidate everything at once: cPanel password, every database user, every application administrator, FTP accounts, SSH keys, API tokens and application passwords. One rotation session, not a trickle over an afternoon — an intruder who keeps one working credential simply waits for you to finish.
Take a full backup of the compromised state before you change anything, and keep it separate from your clean copies. It is your only record of what was there, and you will need it to answer both technical and awkward non-technical questions.
Find the window before you pick a restore point
Two sources bracket it. From the filesystem: find . -type f -name '*.php' -newermt '2026-08-01' or a plain -mtime -14 to list what changed recently. From the log: the first request that does not belong — an odd POST, a request to a path that should not exist, a burst from one address. Together they give you a date, and the restore point is the newest backup before that date.
Resist the newest copy. A compromise that sat quietly for a week is inside every backup taken during that week, and restoring one of those reinstalls the problem with less effort than the attacker originally spent.
Eradication is a list, not a scan
Work the list explicitly: administrator accounts you did not create; PHP files anywhere under uploads; every .htaccess on the account, checked from the top; the crontab, where a scheduled reinfection hides; mail forwarders and filters; must-use plugins and drop-ins that load automatically; and appended code at the end of wp-config.php or the theme's functions file.
Then check whether the site is still sending. cPanel's Track Delivery and the mail queue will show outbound spam if a script is using your account to send it, and that is the symptom most likely to get your domain's reputation damaged long after the files are clean.
Verification, then reputation, in that order
Verify with evidence: wp core verify-checksums clean, no unexpected PHP under uploads, an empty diff against your repository if you deploy from one, the crontab as you expect it, and a TTFB reading back at baseline — a site still doing hidden work for somebody else often reads slow.
Only then go to the search engines. Request the security review in Search Console if you were flagged, resubmit the sitemap, and watch for a fortnight. Reputation recovers after the technical fix lands, never in parallel with it, and asking for a review while a backdoor is still live simply spends your credibility.

The tooling this runbook leans on
Everything here runs on the platform we operate: SSH with WP-CLI, self-service restores from any daily backup, Imunify protection at server level, and cPanel's own mail delivery tracking.
The Nitro tier takes a backup every six hours, which narrows the window you have to restore across when an incident is discovered late.
- Containment sequenced before any cleaning
- Two ways to date the intrusion, both printed
- The backdoor list, item by item
- Engineers on the desk at whatever hour this happens
Why HostingFast
Standard on every plan
Order that makes the fix hold
Contain, date, restore, patch, sweep, verify, then reputation — each step failing differently if you take it out of turn.
Evidence kept, not destroyed
A copy of the compromised state before you change anything, because you will need to know what was there.
One rotation session
Every credential class listed so nothing is left holding a valid login while you clean around it.
The restore point, dated
Filesystem timestamps plus the first anomalous log entry, which together stop you restoring the payload.
Outbound mail checked
Track Delivery and the queue, because a clean filesystem still sending spam is the damage that lasts.
Verification with artefacts
Checksums, an empty diff, a clean crontab and a TTFB reading — things you can show a client.
Quick Start
From order to online
- 1
Preserve the evidence, then take the site down
Download a full backup of the compromised state and put it somewhere separate. Then switch on maintenance mode, so nothing is served to visitors and nothing is written while you work.
- 2
Invalidate every credential in a single pass
cPanel, database users, application administrators, FTP accounts, SSH keys, API tokens, application passwords. All of them, in one session. A rotation spread over an afternoon leaves a working door open for the afternoon.
- 3
Date the intrusion, then restore from behind it
find . -type f -name '*.php' -mtime -14 plus the first anomalous entry in the access log. Restore the newest copy that predates both — daily on every plan, six-hourly on Nitro.
- 4
Patch the entry point before it goes back online
The vulnerable plugin, the abandoned component, the reused password. Restoring without this books the next incident, and the attacker already knows the route.
- 5
Sweep the list, verify, then ask for the review
Admin users, uploads, every .htaccess, cron, mail forwarders, must-use plugins. Then checksums, an empty repository diff, a clean mail queue and a TTFB reading. Search Console last.
Built In
Loaded onto every plan
- Daily backups on every plan, six-hourly on Nitro, restorable by you
- Full SSH access with WP-CLI, Git and Composer on every shared tier
- Imunify protection scanning at server level, below the application
- cPanel Track Delivery for confirming outbound mail is clean
- Staging environments so the rebuilt site can be checked before it goes live
- Free SSL on every plan, renewed automatically before it can expire
- DDoS filtering absorbed out at the network edge
- LiteSpeed caching in the server, with a purge control you own
- Money-back cover: 30 days on hosting plans, 7 on reseller
- Human support on duty every hour of every day
Frequently Asked
What people ask us most often
How do I find the entry point from the access log?
Start at the timestamp of the earliest modified file and read outward from there. You are looking for a POST to something that should not accept one, a request to a plugin path with a suspicious query string, or a burst of requests from a single address just before the first file change. Once you have the request, the component named in its path is usually the vulnerability — and that is the thing that must be patched or removed before the site returns.
Is it faster to rebuild from scratch than to clean?
Often, yes. If you deploy from version control, a rebuild is a clean checkout plus a database you have verified — measured in an hour rather than half a day, with no lingering doubt about a file you missed. Cleaning wins when the site has years of uploads and hand-edited configuration nobody documented. Either way the entry point still has to be patched, and the credentials still have to be rotated.
How do I check the site is no longer sending spam?
cPanel's Track Delivery shows recent outbound messages and their fate, and the mail queue shows anything stuck. If you see volume you did not generate, a script is still sending: look for scheduled tasks, mail forwarders you did not create, and PHP under uploads. This is worth confirming explicitly, because outbound spam damages your domain reputation for far longer than the defacement was visible.
What order do the cache and CDN purges go in afterwards?
Innermost first: the object cache, then the LiteSpeed page cache, then the CDN edge, then your own browser. Injected content lives in each of those layers independently, and purging the edge while a poisoned page sits in the origin cache simply re-populates it. Do it after the files and database are clean, never before.
Keep reading
How to Put WordPress in Maintenance Mode
Take the site off the air properly, with the right status code while you work.
How to Reduce Server Response Time
Decompose TTFB into DNS, TLS and server time before you spend an afternoon on it.
DNS (Domain Name System) (Glossary)
How a name resolves, and which record an intruder would want to change.
Web Hosting
NVMe behind a LiteSpeed cache, with free SSL and Imunify on every account.
WHMCS License
A standalone WHMCS licence for running your own billing and provisioning.
Changing hosts? Run through our checklist first.
A straightforward sequence for a switch your visitors never feel: which files move first, how to shift email across without losing a single message, the right moment to repoint DNS, and the two mistakes behind almost all the downtime we get asked to rescue.
Recover on a platform with the tools in it.
Self-service restores from daily backups, six-hourly on Nitro, Imunify at server level, SSH with WP-CLI, and engineers on the desk at any hour.
View Web Hosting plans