Malware Cleanup: How to Effortlessly Bulk Trash Malicious Posts with an MU-Plugin

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.

Step 1: Prepare Your Environment

  1. 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?

  2. 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.

  1. 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.
  2. Create the Plugin File: Inside the mu-plugins directory create a new file named bulk-trash-infected-posts.php.
  3. 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 );
    });
    
    
  4. Save the File: Once you’ve added the code, save the file. The mu-plugin will now automatically run when you access WordPress.
  5. Visit Trash: Visit trash to review and permanently purge the entire trash.
  6. 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!

This article is written by Evelyn Allison. Evelyn has over two decades of experience with the big-tech corporate giants. Starting in 2002 with consumer IT remote support, he transitioned into IT enterprise support and systems provisioning for Windows and Linux servers. Her prowess spans her expertise in network security, security audit and scripting-based-automation. Actively involved in web security since 2017, Evelyn has worked with various technologies to secure the web, leveraging tech like Nginx, modsecurity, reverse-proxies, developing web-application-firewalls, on-the-fly asset optimization using Google’s PageSpeed Module and more. Her expertise is reflected in the top-tier plugins and comprehensive consulting-services she offers in the domain of web-security.