Blog / WordPress/ Automatically Clean Up Inactive Malicious User Registrations in WordPress (Complete Code Included)

Automatically Clean Up Inactive Malicious User Registrations in WordPress (Complete Code Included)

WordPress 定时清理从未登录的恶意注册用户(附完整代码)

Many WordPress site administrators face the problem of malicious user registrations. For instance, some sites have been flooded with over 700,000 fake users, causing the database to bloat by more than 1GB in a short time, severely impacting site performance and security.

To solve this, we can use WordPress's built-in cron system to automatically clean up users who have never logged in. This article provides a complete, safe implementation.

How It Works

The core of this solution is to create a custom WordPress cron job. This task runs periodically to query and delete users matching specific criteria (e.g., users who registered but never logged in).

Complete Implementation Code

Add the following code to the end of your current theme's functions.php file, or use a code snippet plugin like Code Snippets.

/**
 * 1. Add a custom cron interval (e.g., every 10 minutes)
 */
add_filter( 'cron_schedules', 'wp_cleanup_add_cron_interval' );
function wp_cleanup_add_cron_interval( $schedules ) {
    $schedules['every_ten_minutes'] = array(
        'interval' => 600, // 600 seconds = 10 minutes
        'display'  => __( 'Every 10 Minutes', 'your-text-domain' )
    );
    return $schedules;
}

/**
 * 2. Schedule the cron event (if not already scheduled)
 */
if ( ! wp_next_scheduled( 'wp_cleanup_inactive_users_hook' ) ) {
    wp_schedule_event( time(), 'every_ten_minutes', 'wp_cleanup_inactive_users_hook' );
}

/**
 * 3. Define the cleanup function
 */
add_action( 'wp_cleanup_inactive_users_hook', 'wp_cleanup_inactive_users' );
function wp_cleanup_inactive_users() {
    // Get all users
    $all_users = get_users( array( 'fields' => array( 'ID', 'user_registered' ) ) );

    foreach ( $all_users as $user ) {
        $user_id = $user->ID;
        $user_data = get_userdata( $user_id );
        $user_roles = $user_data->roles;

        // Criteria: Delete 'subscriber' users registered over 7 days ago with zero posts/comments
        $days_old = 7;
        $registered_time = strtotime( $user->user_registered );
        $cutoff_time = strtotime( "-$days_old days" );

        $post_count = count_user_posts( $user_id );
        $comment_count = get_comments( array( 'user_id' => $user_id, 'count' => true ) );

        if ( in_array( 'subscriber', $user_roles ) &&
             $registered_time < $cutoff_time &&
             $post_count == 0 &&
             $comment_count == 0
        ) {
            require_once( ABSPATH . 'wp-admin/includes/user.php' );
            wp_delete_user( $user_id );
        }
    }
}

/**
 * 4. (Optional) Clean up cron task on plugin/theme deactivation
 */
register_deactivation_hook( __FILE__, 'wp_cleanup_deactivation' );
function wp_cleanup_deactivation() {
    $timestamp = wp_next_scheduled( 'wp_cleanup_inactive_users_hook' );
    if ( $timestamp ) {
        wp_unschedule_event( $timestamp, 'wp_cleanup_inactive_users_hook' );
    }
}

Code Explanation & Safety Tips

1. Custom Interval

The cron_schedules filter adds a 10-minute interval. You can adjust the interval value (in seconds) for hourly (3600) or daily (86400) runs.

2. Core Cleanup Logic

The rewritten code uses a safer, multi-condition strategy:

  • Target Role: 'Subscriber'.
  • Registration Age: Older than the set number of days (7 in the example).
  • Activity Check: Zero published posts and zero comments.

Combining these conditions minimizes the risk of deleting legitimate users while targeting inactive, likely malicious registrations.

3. User Deletion Note

The wp_delete_user() function requires a $reassign parameter for users who own posts, or their posts will be deleted. Our logic ensures $post_count == 0, so deletion is safe.

4. Managing Cron Tasks

  • View Tasks: Use plugins like 'WP Crontrol' to see and manage custom cron jobs.
  • Stop Cleanup: Remove the code from functions.php or deactivate the snippet. The provided deactivation hook serves as an example.

Extension: Track User Last Login

For precise 'never logged in' detection, track the last login time. Add this to your functions.php:

// Record user login time
add_action( 'wp_login', 'wp_record_user_last_login', 10, 2 );
function wp_record_user_last_login( $user_login, $user ) {
    update_user_meta( $user->ID, 'last_login', current_time( 'mysql' ) );
}

After adding this, you can modify the main cleanup function to check if the last_login user meta exists. If it doesn't, the user hasn't logged in since you added the tracking code.

This solution helps automate user cleanup, keeping your WordPress database lean and efficient.

Post a Comment

Your email will not be published. Required fields are marked with *.