Prevent duplicate accounts from the same IP

I needed a way to prevent users from opening multiple accounts, so the best idea I had was to save their IP when they register and then check against existing IPs during registration.

Here's what I did.

In the start.php init() function of an existing custom plugin I have, I added:

// IP logging
register_elgg_event_handler('create', 'user', 'MYPLUGIN_log_ip');

Then, also in start.php, I had to define this new function:

   // Save IP address of new users
    function MYPLUGIN_log_ip($event, $object_type, $object)
    {
     if (($object) && ($object instanceof ElggUser))
     {
       $ip_address = $_SERVER['REMOTE_ADDR'];
       create_metadata($object->guid, 'ip_address', $ip_address, '', 0, ACCESS_PUBLIC);
     }
    }

Ok, so that's step 1.  Now the IP of every new user is saved as metadata.  The second step is using these saved IPs to prevent new accounts being added with existing IPs.

I'm using the Site Access plugin, so I modified the /MYDOMAIN.com/mod/siteaccess/views/default/account/forms/register.php file and added this near the top:

$ip_address = $_SERVER['REMOTE_ADDR'];
// find_metadata($meta_name="",$meta_value="",$entity_type=""",$entity_subtype="",$limit=10,$offset=0,$order_by="",$site_guid=0)
$ip_metadata = find_metadata("ip_address",$ip_address,"user");
 
if (is_array($ip_metadata))
  $form_body = '<br /><b>Error:</b><br />An account already exists for your IP address.<br /><br />If you feel this shouldn\'t be the case, please contact support</a>.';          
else
{

// normal Site Access logic

}

If you aren't using Site Access then I'd suggest you look at how it overrides the core registration form and mimic that in your own code.

So now I've prevented 99% of users from registering an account with an existing IP.  But I haven't prevented the "smart" haxxors that can spoof a POST or GET of an HTML form.  I've hidden the form but I haven't done anything to prevent someone from still triggering the action.

Rather than trying to override the core actions/register.php file (a hook wouldn't suffice because I need to prevent registration entirely, not just add a function after it happens), I decided to take the easy way out and just modify it.  So near the top I added this code:

// Validate IP already exists
    $ip_address = $_SERVER['REMOTE_ADDR'];
    // find_metadata($meta_name="",$meta_value="",$entity_type=""",$entity_subtype="",$limit=10,$offset=0,$order_by="",$site_guid=0)
    $ip_metadata = find_metadata("ip_address",$ip_address,"user");
 
  if (is_array($ip_metadata))
  {
    register_error("<b>Error:</b><br />An account already exists for your IP address.<br /><br />If you feel this shouldn't be the case, please contact support.");
    forward();
  }
  else
{

// normal action stuff

}

Hopefully that helps someone trying to do the same thing!  If anyone has a better method I'm all ears too.

  • Forget my last post, I don't think that section is supposed to be there, might just be a bug in the throttle plug-in.

  • Step 1 and Step 2 should be in the start.php of a plugin.

  • @Team Webgalli no sorry that doesn't work. I moved the code to the start.php and the second I activate the plug-in I receive a blank white page across the entire site. As suggested this is the content of the start.php file:-

    <?php
    /**
     * Describe plugin here
     */

    // IP logging
    register_elgg_event_handler('create', 'user', 'duplicate_ip_log_ip');

       // Save IP address of new users
        function duplicate_ip_log_ip($event, $object_type, $object)
        {
         if (($object) && ($object instanceof ElggUser))
         {
           $ip_address = $_SERVER['REMOTE_ADDR'];
           create_metadata($object->guid, 'ip_address', $ip_address, '', 0, ACCESS_PUBLIC);
         }
        }


    elgg_register_plugin_hook_handler("action", 'register', 'register_action_hook',1);

    function register_action_hook($hook, $entity_type, $returnvalue, $params) {
    $ip_address = $_SERVER['REMOTE_ADDR'];
    if($ip_address){
    $user = elgg_get_entities_from_metadata(array('type'=>'user', 'limit'=>1, 'metadata_name'=> 'ip_address', 'metadata_value'=>$ip_address)
    if($user){
    register_error(elgg_echo('duplicate:account:exists'));
    forward(REFERER);
    }
    }
    }

     

    ?>

  • There is a typo in the code. put a " ); " at the end of 

    $user = elgg_get_entities_from_metadata(array('type'=>'user', 'limit'=>1, 'metadata_name'=> 'ip_address', 'metadata_value'=>$ip_address)

    To troubleshoot white page see http://docs.elgg.org/wiki/White_page

  • Yes that works I woke up to only a few spams this morning which was much easier to delete so thank you @Team Webgalli

    I know it isn't a long term solution or even perfect, but it is a handy and quite lethal weapon to have at my disposal when need be, so thanks again.

  • I think an idea is to make a permenent cookie(which should be deleted while at the time of formatting the system),

    while people visiting the website

    if in cookie there is an already logged session of the site

    {

    , hide the registration page through server side scripting.

    }

    else (there is no logged session)

    {

    show the registration page

    }

    But all these ideas are neither 100% reliable nor 100% percent consistent. To forbid the registration through ip or any other process, it is only applicable at the time when all people are using unique computers by their own..

  • Any updates to this for 1.9? I would definitely be interested in this spam limiting since none of the plugins I've found have this option in them.