Recently, during a malware service ticket, we discovered around 4583 spam / malware-infected posts on a client’s WordPress site. Manually cleaning up such a large number of posts would have been a nightmare. So we created a must-use plugin (mu-plugin) to automate the cleanup process. Follow the steps below to build your own nifty mu-plugin to quickly bulk trash these malicious posts.
Table of Contents
Step 1: Prepare Your Environment
- Identify the Infected Posts: Create a list of infected post IDs by running a full malware scan or reviewing your security logs. This will be your target list of posts for the cleanup process.
Did you know Malcure Malware Scanner scans the database and lists all infected post IDs for you?
- Backup Your Site: Critical step! Ensure you have a complete backup of your website before running any cleanup scripts to avoid accidental data loss.
Step 2: Create the mu-plugin
Mu-plugins are automatically activated by WordPress and cannot be accidently disabled via the admin dashboard. They are enabled simply by uploading file to the mu-plugins directory, without having to log-in. This makes them ideal for emergency tasks like malware cleanup.
- Locate or Create the mu-plugins Directory: Navigate to your WordPress installation and locate the
wp-content/mu-plugins
folder. If it doesn’t exist, create it. - Create the Plugin File: Inside the mu-plugins directory create a new file named
bulk-trash-infected-posts.php
. - Add the Following Code: Paste the code below into your newly created file. This code breaks the list of post IDs into batches of 50 and trashes each one, ensuring a smooth clean-up process for a large number of posts.
<?php /** * Plugin Name: Bulk Trash Infected Posts (MU) * Description: A simple MU plugin to move a list of post IDs to trash in batches of 50. * Version: 1.0 * Author: Shiv */ if ( ! defined( 'ABSPATH' ) ) { exit; } /** * Trashes an array of post IDs in batches of 50. * * @param array $post_ids Array of post IDs to be trashed. */ function bulk_trash_posts_in_batches( array $post_ids ) { if ( empty( $post_ids ) ) { return; } foreach ( array_chunk( $post_ids, 50 ) as $chunk ) { foreach ( $chunk as $post_id ) { if ( get_post( $post_id ) ) { wp_trash_post( $post_id ); } } } } /** * Trigger the cleanup on admin initialization. * Replace the placeholder array with your infected post IDs. */ add_action( 'admin_init', 'bulk_delete_execute'); function bulk_delete_execute() { $post_ids = [ 5531, 5534, 5539, 5557 /* ... add additional post IDs here ... */ ]; bulk_trash_posts_in_batches( $post_ids ); });
- Save the File: Once you’ve added the code, save the file. The mu-plugin will now automatically run when you access WordPress.
- Visit Trash: Visit trash to review and permanently purge the entire trash.
- Don’t forget to Delete: Don’t forget to delete this plugin once you are done.
Step 3: Customize the Code
- Edit the Post IDs Array: Replace the sample post IDs in the code with the actual IDs of the infected posts you want to trash.
- Adjust Batch Size (Optional): If you prefer a different batch size than 50, adjust the number in the
array_chunk()
function accordingly.
Step 4: Execute the Plugin
Trigger the cleanup by accessing your WordPress admin area. Since the mu-plugin is hooked into admin_init
, visiting the admin dashboard will automatically execute the code.
Step 5: Verify the Trashed Posts
After the mu-plugin runs, navigate to your WordPress admin dashboard and check the Trash section to ensure that the infected posts have been moved there.
Note: Always exercise caution when deleting posts in bulk. Double-check the list of post IDs to ensure that only infected or unwanted posts are targeted.
Quick Tip: You can also bulk trash or delete infected posts via WP CLI also which we’ll cover in the next post — stay tuned for more security tips!