Step-by-step cleanup guide
How to fix a hacked WordPress site: 12 calm steps, in order
Work through these steps in order to remove what the attacker left behind, then use the last section to find out how they got in so it does not happen again.
.htaccess and wp-config.php, and clean injected code out of the database. Update everything, ask Google for a review if the site was flagged, and monitor for a few weeks. Then find out how the attacker got in, or it will probably happen again.First, be sure the site is really hacked. Our diagnostic checklist helps, and the website hacked guide covers the first 60 minutes for a non-technical owner. Steps 1 to 3 below repeat the essentials, so skip ahead if you have done them.
You will need your hosting file manager or SFTP, and phpMyAdmin. Some steps show optional WP-CLI commands for hosts with shell access. If you add other WP-CLI commands on an infected site, add --skip-plugins --skip-themes so untrusted code is not loaded. If you are not comfortable editing files and databases, stop after step 2 and ask for help. Deleting the wrong file, such as wp-config.php, takes the site down.
Could you restore a clean backup instead? Only if it predates the infection, and it still brings back the same vulnerable plugins and passwords. You would still do steps 3 and 10 to 12.
Part 1: Contain it (steps 1 to 3)
1. Back up the hacked site as it is
Download all files and export the database, even though they are infected. Keep this copy away from the server. It is evidence that helps you find the entry point, and you must never restore it to the live site. Ask your host for the access and error logs from the last few weeks, and for their own backups.
2. Put the site in maintenance mode
Stop visitors and Google from getting malware or spam. Use your host’s maintenance page, password-protect the site from the hosting panel, or point the domain at a plain static page. Avoid relying on a plugin on a site you cannot trust yet. If your host suspended the site, ask what they found.
3. Change every password and key
- Scan your own computer first. If the attacker stole a password from an infected laptop, new passwords typed there are stolen too.
- Hosting account, FTP/SFTP/SSH users and the email account of the WordPress admin, because password resets are sent there.
- The database password. Then update
DB_PASSWORDinwp-config.phpto match, or the site will show “Error establishing a database connection”. - Every WordPress user, not just admins. Delete any Application Passwords you do not recognise (Users, then Profile).
- API keys and tokens the site uses, such as payment, email and CRM keys.
- The WordPress keys and salts. Replace the eight lines from
AUTH_KEYtoNONCE_SALTinwp-config.phpwith fresh values fromapi.wordpress.org/secret-key/1.1/salt/. Everyone who is logged in, including an attacker, is logged out.
Part 2: Clean it (steps 4 to 9)
4. Scan the files and compare core against a clean copy
Run a malware scanner from your host or a security plugin from the official WordPress.org directory to get a list of suspects. A scanner only finds known patterns, so treat it as a start, not proof the site is clean. Then check core against the official files:
- With WP-CLI:
wp core verify-checksumscompares your core files with the checksums published by WordPress.org. Add--include-rootto be warned about unknown files in the root folder.wp plugin verify-checksums --alldoes the same for plugins from WordPress.org. - Without shell access: download the same WordPress version from wordpress.org, unzip it, and compare it with your site using a file-compare tool.
wp-adminandwp-includesshould match exactly. Any extra file in either folder is suspicious, and so is any PHP file in the root that is not part of WordPress.
5. Reinstall core, plugins and themes from official sources
Core. The Re-install button under Dashboard, then Updates, overwrites core files but does not delete extra files an attacker added. For a full clean, delete wp-admin, wp-includes and the loose core files in the root (index.php, wp-*.php except wp-config.php, xmlrpc.php, license.txt, readme.html), then upload fresh copies from wordpress.org. Do not touch wp-config.php or wp-content at this stage.
Plugins. Deactivating is not enough. Delete each folder in wp-content/plugins and install a fresh copy from the official directory or the vendor’s own site. Settings are stored in the database, so they usually survive. Delete plugins you no longer use. A pirated (“nulled”) plugin must go for good: replace it with a licensed copy or an alternative.
Themes. Do the same, and keep one default theme. If you edited a theme or use a child theme, read your custom code. Look for things you did not write, such as eval(, base64_decode(, gzinflate(, long unreadable strings, or script tags pointing to domains you do not know. Some of these functions have honest uses, but they are rare in themes.
Auto-loaded code. Check wp-content/mu-plugins and drop-in files such as advanced-cache.php, object-cache.php and db.php. WordPress loads these on its own, so attackers hide code there. Some hosts add genuine ones, so ask your host if you are unsure.
6. Remove unknown admin users
Open Users, filter by Administrator, and delete accounts you do not recognise. When asked, give their content to a trusted user instead of deleting it. Check editors and other roles too. Some malware hides an admin from the dashboard list, so also open the wp_users and wp_usermeta tables in phpMyAdmin (your table prefix may differ) and compare them with what the Users screen shows.
7. Look for PHP files where none belong
wp-content/uploads should hold media only. With shell access, run find wp-content/uploads -type f -iname "*.php*" from the site’s root folder to list PHP files there. Without it, browse the folders in your file manager or SFTP and look for .php files, double extensions such as image.jpg.php, and hidden files. A tiny index.php that only says “Silence is golden” is normal. Copy anything else into your evidence folder, then delete it.
Also look for PHP files with random names anywhere else. find . -name "*.php" -mtime -14 lists PHP files changed in the last 14 days. Attackers can fake dates, so do not trust it alone. Then open your host’s Cron Jobs list and remove entries you did not create, especially any that download from an outside address (see why WordPress sites keep getting hacked).
8. Check .htaccess and wp-config.php
.htaccess (Apache and LiteSpeed hosts). Look for rules that redirect visitors to other sites, especially visitors from search engines, plus auto_prepend_file lines and handler lines that make non-PHP files run as PHP. The easy fix is to rename the file, then go to Settings, Permalinks and click Save Changes. WordPress writes a clean default. Re-add only the custom rules you know you need. Check for stray .htaccess files in subfolders, and for .user.ini or php.ini files containing auto_prepend_file, which runs code on every page.
wp-config.php. Open it in a text editor and compare it with wp-config-sample.php from the fresh download. Be suspicious of code above the opening <?php tag, long encoded strings, eval or base64_decode, includes of files you do not know, and anything after the final require_once ABSPATH . 'wp-settings.php'; line. When it is clean, rotate the database password and the salts a second time, because a backdoor you have not found yet could have read the old ones. You can also add define( 'DISALLOW_FILE_EDIT', true ); to switch off the dashboard code editor. Set permissions to 755 for folders and 644 for files. WordPress’s own hardening guide suggests 400 or 440 for wp-config.php. Never use 777.
9. Clean the database
Export a fresh database backup first. Then search the whole database for <script, <iframe, eval( and base64_decode, using the Search tab in phpMyAdmin or wp db search "<script" --all-tables. Many hits are honest embeds and tracking code, so judge each one. Pay attention to:
- Posts and pages: hidden links, iframes and spam text inside
post_content. - Options:
siteurlandhomemust be your real address. Look throughactive_pluginsfor plugins you do not know, plus widgets and the theme’s Additional CSS. - Spam content: delete pharmacy, casino or foreign-language pages and comments you never published. See the Japanese keyword hack if thousands of them appear.
Do not run a plain SQL REPLACE on options or widgets. They are stored as serialized data, and changing the text length breaks them. Edit them in the dashboard, or use wp search-replace, which handles serialized data.
Part 3: Recover and monitor (steps 10 to 12)
10. Update everything and tighten the basics
- Update core, plugins and themes. Remove abandoned ones that no longer get updates.
- Ask your host to run a supported PHP version.
- Turn on two-factor login for every admin, give each person their own account, and keep the number of admins small.
- Keep automatic backups off the server, and test that you can restore one.
11. Ask Google to review the site (if it was flagged)
Do this only if you saw “This site may be hacked”, “Deceptive site ahead” or an item in Search Console. First take the site out of maintenance mode and check that pages, login, forms and checkout work, so Google can see the clean site. Also check Search Console, under Settings, then Users and permissions, for owners you do not recognise and remove them. Then open Security issues, fix every listed issue on every page, and choose Request review. Explain what was wrong, what you did and the result. Google says reviews can take from a few days to a few weeks, and you should not resubmit while one is pending. More in our guides to the “this site may be hacked” warning and the Security Issues report.
12. Monitor for the next few weeks
Check the user list, plugin list and uploads folder every few days. Watch Search Console, and search site:yourdomain.com in Google for spam pages. Turn on file-change and uptime alerts from your host or a security plugin. If anything comes back, the entry point is still open. That is the next section.
Why hacked WordPress sites get hacked again
Everything above removes what the attacker left behind. It does not close the door they used. These are the usual doors:
- A plugin or theme with a known flaw that was never updated.
- A pirated (“nulled”) plugin or theme that carries a backdoor.
- A weak or reused password, or a login stolen from an infected computer.
- A hidden backdoor or scheduled task that the cleanup missed.
- Another site on the same hosting account that is still infected.
The full explanation is in why a WordPress site keeps getting hacked. You can find some of these yourself. Compare the date of the first changed file with your logs, and check which plugin versions were vulnerable at that time. The rest takes a person who knows where to look.
Finding how they got in is the real fix
Our job is the part a cleanup skips: finding and fixing the weakness that let the attacker in. Once your site is clean, a real security expert audits it by hand and hands you a written report: every issue with severity, evidence, plain-English impact and exact fix steps. Reports usually arrive within about 5 business days after you verify your domain. We only test sites you own or are authorized to test, with a recorded Authorization to Test.
- Circuit, $49 one-time: the full manual audit of one website, so you know what to close. Get Circuit. See a sample report.
- Signal, $299 for 3 months: everything in Circuit, plus we fix the high and critical issues with you, re-test them and keep watch as you ship changes. Get Signal.
Costs for the whole recovery are in what it costs to fix a hacked website. Customers rate Bug Circuit 5.0 out of 5.
Frequently asked questions
Can a hacked WordPress site be recovered?
How do I know if my WordPress site is hacked?
What is the best WordPress malware removal tool?
Can I just restore a backup instead?
How long does Google take to review a hacked site?
How do I secure WordPress from hackers?
Can Bug Circuit help after my WordPress site was hacked?
Keep reading
Check what attackers can see, for free
Run the free passive check on your domain. No login, no card, no impact on your site. Then decide if you want a manual audit to close the door.
Ready for the full manual audit? See pricing