WordPress malware keeps coming back: the file that rebuilt it from the database

In September 2026 we cleaned the same malware off a group of small business sites again and again. Each time the files came back. The reason was a small file hiding in the uploads folder that rewrote the malware from a copy stored in the database. This is how we found it, and how to make sure a cleanup sticks.

By the Moatline team at Next Nova Technologies · Published 29 October 2026 · 4 min read

This is a real cleanup from September 2026, on several WordPress sites we look after for small businesses. We’ve left out their names. Everything else is as we found it.

What kept happening

The sites carried malware in wp-content/mu-plugins, the folder for must-use plugins. Files there run on every page and don’t appear on the Plugins screen, which makes it a favourite hiding place. We deleted them and the scan came back clean. Then the same files were back.

What we found

  • A small PHP file in the uploads folder called wp-cache-stats.php. The name sounds like a caching plugin’s statistics file. Nothing like it belongs in uploads.
  • A copy of the malware in the database. An entry in wp_options called _wp_cron_lock_status held the malware’s PHP code, encoded in base64. The name is made to look like one of WordPress’s own housekeeping settings.
  • The link between them. When wp-cache-stats.php ran, it read that database entry, decoded it and wrote the must-use plugin files back to disk. Whoever controlled it could trigger the rebuild whenever they wanted.
Removing the visible malware without the uploads file and the database copy is like painting over damp: it looks fine until the next morning.

Why deleting files didn’t work

Each cleanup removed what was easy to see, the files in mu-plugins. The two pieces that rebuilt them were easy to miss: one sat in a folder people rarely open, and the other was a database entry, which scanners that only read files never look at. Across these sites we eventually identified eight different malware families, but this pair was the one that kept undoing our work.

Moatline grew out of this cleanup. It flags every PHP file in uploads and says what it can do (for this one, that it “reads restore payload from DB”), and it checks the database for code stored in settings, not only the files.

The cleanup order that works

  1. Find everything before you delete anything. Files in mu-plugins, PHP files in uploads, plugins you don’t recognise, database entries holding long encoded text, scheduled tasks and administrator accounts. If you remove one piece while another is still running, it can put the first back.
  2. Back up the files and database as they are, so you can look back later.
  3. Remove all of it in one go: the uploads file first, then the database copy, then the files it wrote, then fake plugins and unknown administrators.
  4. Block PHP in uploads so a new file there can’t run. Moatline does this with one click on Apache and LiteSpeed servers and shows the rule for nginx.
  5. Change every password and the keys in wp-config.php, including hosting, FTP and database passwords, and log everyone out.
  6. Watch for three days. Scan daily and compare the mu-plugins and uploads folders with the day before.

Check your own site

  • Open wp-content/uploads and search it for .php files, including names like .php5, .phtml or images that end in .php.
  • Open wp-content/mu-plugins. If you don’t know what a file there does, find out before you trust it. Some hosts add their own, so check with your host.
  • In phpMyAdmin, sort wp_options by the size of option_value and look at the biggest entries. Long blocks of random-looking letters under a name you don’t recognise deserve a closer look.
  • Or run the free Moatline Malware Scanner, which checks all three.

Related: how to remove malware from WordPress and fake CAPTCHA malware hidden in the database.

Don’t want to do this yourself? Our team cleans hacked WordPress sites every week: WordPress malware removal service, from $45, usually done within 24 hours.

Frequently asked questions

Why does my WordPress malware come back after I delete it?
Usually because something you didn’t find puts it back: a second file such as a webshell in uploads, a copy of the code in the database, a scheduled task, an extra administrator account or a stolen password. Deleting only the files you can see leaves that in place.
Can a PHP file in wp-content/uploads be legitimate?
Almost never. Uploads is for images and documents. A handful of plugins keep an index.php there to stop folder listings, but a PHP file that does anything else is a red flag.
Will restoring a backup stop the reinfection?
Only if the backup is from before the first infection and you change every password and the wp-config.php keys straight after. A backup that already holds the database copy or the uploads file brings the problem straight back.
How long should I watch the site after a cleanup?
At least three days, with a scan each day. Rebuild tricks like this often run once a day or when a page is visited, so a clean result on day one doesn’t prove much.

Scan your site for free

Moatline checks files, the database and page-builder content. Nothing changes unless you click a button.

More guides

All guides →