Bots, Open Registration and Disposable Emails

Tech Articles | March 18, 2025 | Blog, Coding, GridPane, SureCart, Wordpress

I recently released a few additional plugins for free and have added a requirement that to get access; you need access to the dashboard of https://reallyusefulplugins.com

This allows you to access a new dashboard tab added with Dashy for Surecart to the free plugins I have available, as can be seen below a simple shortcode outputting them and links to download.

Now to do this I had to open up the dreaded allow registrations on the WordPress site and this is something I hate to do due to spam, I already use CloudFlare and WP Armour on this site as well as Solid Security and WAF from Gridpane so it is pretty secure.

Like all security though its a balancing act between secure and user friendly and its a fine line to walk and I think with this site I have it about right for now.

So I did the above-opened registrations and added a link to the Dashy and URL Parameters page, and all was well for about 48 hours then, when I woke up Sunday morning to almost 600 new registrations from mainly yopmail and other such disposable mail providers.

This was easily fixed. I indescrimently deleted them all as long as they hadn’t made an actual purchase in SureCart, and that was it fixed, but it got me wondering if I can stop this as I don’t want to repeat this every time and stopping it at source is better.

So I set about looking for lists firstly of such providers and seeing if they existed and I found one such opensource list on Github a simple conf file containing such providers and its updated regularly with an update in the last week so I knew I was on to a winner.

Second was considerations, I don’t want free disposable email addresses having accounts but I appreciate and support privacy for my paying customers so I need them to be able to create accounts and buy a product using such tools if they wish but prevent free accounts from using such providers.

So I began work on how to fix this and knew I wanted to use this list as well as a custom list for domains and providers I didn’t want to support so I needed to be able to look at this list and cache it and from there I needed to be able to add domains to my own list and for this I choose Pastebin over gist and the reason for this was caching if I add a domain I want to be able to delete the transients and recache but gist has pretty heavy caching even for raw versions.

I have a PasteBin pro Account so that’s what I decided to use and created a list to which I added cloak.id to although not a disposable provider as such it was a good one to add to my list.

The next problem is how to prevent public signup and not affect SureCart creation; well, it turns out Sure Cart uses its own way of creating users and doesn’t have the same hooked nature to registration errors as the default form.

So, actually, as long as I could get this working for the native form, it wouldn’t affect sure cart sales, so they would be free to use whatever email account they wished. After all, I respect Privacy, and the whole sign-up for an account is a lead magnet to get them added to my distribution list.

The below is the snippet I came up with, and it appears to work exactly as intended.

<?php 
/**
 * Retrieve a list of domains from a remote URL and cache it as a transient.
 *
 * @param string $url           Remote URL to fetch the list.
 * @param string $transient_name Name of the transient to store the list.
 * @param int    $cache_duration Cache duration in seconds.
 * @return array List of domains.
 */
function get_remote_domains_list( $url, $transient_name, $cache_duration = 7 * DAY_IN_SECONDS ) {
    $domains = get_transient( $transient_name );
    if ( false === $domains ) {
        $response = wp_remote_get( $url );
        if ( is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) !== 200 ) {
            return array();
        }
        $body = wp_remote_retrieve_body( $response );
        $lines = explode( "\n", $body );
        $domains = array();
        foreach ( $lines as $line ) {
            $line = trim( $line );
            // Ignore empty lines and comments.
            if ( empty( $line ) || strpos( $line, '#' ) === 0 ) {
                continue;
            }
            $domains[] = strtolower( $line );
        }
        set_transient( $transient_name, $domains, $cache_duration );
    }
    return $domains;
}

/**
 * Combine the default disposable email domains list and a custom list.
 *
 * @return array Combined list of disposable email domains.
 */
function get_combined_disposable_email_domains_list() {
    // URL for the default list.
    $default_list_url = 'https://raw.githubusercontent.com/disposable-email-domains/disposable-email-domains/refs/heads/main/disposable_email_blocklist.conf';
    // URL for your custom list (update this URL to your actual raw Pastebin URL).
    $custom_list_url  = 'https://pastebin.com/raw/GnA8Gyt5';

    $default_list = get_remote_domains_list( $default_list_url, 'disposable_email_domains_list' );
    $custom_list  = get_remote_domains_list( $custom_list_url, 'custom_disposable_email_domains_list' );

    // Merge and remove duplicates.
    $combined_list = array_unique( array_merge( $default_list, $custom_list ) );
    return $combined_list;
}

/**
 * Block registration if the email domain is disposable.
 *
 * @param WP_Error $errors               Registration errors.
 * @param string   $sanitized_user_login Sanitized username.
 * @param string   $user_email         User email.
 * @return WP_Error Updated registration errors.
 */
function block_disposable_email_addresses( $errors, $sanitized_user_login, $user_email ) {
    $combined_list = get_combined_disposable_email_domains_list();
    $email_domain  = strtolower( substr( strrchr( $user_email, "@" ), 1 ) );

    if ( in_array( $email_domain, $combined_list ) ) {
        $errors->add(
            'disposable_email',
            __( 'Error: Registration with disposable email addresses is not allowed. Please use a valid email address.', 'textdomain' )
        );
    }
    return $errors;
}
add_filter( 'registration_errors', 'block_disposable_email_addresses', 10, 3 );

//Use to Delete Transients if an immmediate update is required
//delete_transient('disposable_email_domains_list');
//delete_transient('custom_disposable_email_domains_list');

PHP

Support the Author

buy me a coffee
Really Useful Plugin Logo
Appoligies for any spelling and grammer issue. As a dyslexic i need to rely on tools for this they like me are not perfect but I do try my best