reCAPTCHA not stopping spammers?

Asked by Michael

Since making our Jisko based site live a couple of days ago there have been numerous registrations with silly names, but no profile set-up and nothing posted. Their email addresses are all gmail, yahoo, etc., so I can only assume that they're spam-bots which are somehow getting around the reCAPTCHA.

I've read that this is happening on other systems too, but don't remember anyone suggesting a fix except changing the CAPTCHA plugin or method. Is anyone else having this problem?

Question information

Language:
English Edit question
Status:
Solved
For:
Jisko Edit question
Assignee:
No assignee Edit question
Solved by:
Michael
Solved:
Last query:
Last reply:
Revision history for this message
Andivista (andi19642004) said :
#1

Yes, this is terrible, i got hundreds of spammers with strange names like dgfzsfaa zfbkdghfa or something like that.

Revision history for this message
Andivista (andi19642004) said :
#2

Yesterday, i put the Register Site with another name to another place . l will see how long it goes well.

Revision history for this message
Michael (michael-lincme) said :
#3

Andivista, do you mean you've change the registration php to use another Captcha service..?

Revision history for this message
Andivista (andi19642004) said :
#4

No i mean that i have deleted register.php ( from themes ) and put my file ( not the original ) to another folder and renamed it ( reg.php ).

Revision history for this message
Rubén Díaz (outime) said :
#5

We have the same problem @ Jisko.net. reCAPTCHA only avoid automatic
registering bots. But anyone (human) can register an user and then use
API or web to spam.

We've thought about Akismet or any system like, but I don't know if it
will work as expected. Any suggestion?

Rubén

On Fri, Aug 6, 2010 at 15:21, Andivista
<email address hidden> wrote:
> Question #120148 on Jisko changed:
> https://answers.launchpad.net/jisko/+question/120148
>
> Andivista posted a new comment:
> No i mean that i have deleted register.php ( from themes ) and put my
> file ( not the original ) to another folder and renamed it ( reg.php ).
>
> --
> You received this question notification because you are an answer
> contact for Jisko.
>

--
Rubén Díaz
GPG id 2354DA5F
http://diazr.com
(+34) 644 46 93 64

Revision history for this message
Michael (michael-lincme) said :
#6

@Andivista; That's a common measure to try and fool spam-bots, but not a great method.

@Rubén; Yeah, it seems one of the biggest problems now is slave labour being used to register as a human, then the name and password being used in scripts to spam the site. It's already annoying on our site, and I may try and implement the reCaptcha on the log-in page permanently, so bots can't get in all the time. Annoying for users though.

There's another related problem, well actually two;

1. There's no Admin option to delete users and all of their associated posts, files and images. Deleting them from the database with phpMyAdmin leaves orphaned stuff on the server, which can't be deleted because the site scripts created the content. Asking sysops to remove stuff all the time will soon annoy them!

2. The Admin's User page is awful to use as you can't see how many users you actually have. Clicking on A, B, C, D, etc., is very tedious.

Any chance on things like this being updated any time soon, or is the project treading water..?

Revision history for this message
Andivista (andi19642004) said :
#7

For deleting users i have written my own tool ( username, id, confirmation ) http://twitpic.com/2c97yj Spammers: Since more than 48 hours i have no Spammers with my method :)

Revision history for this message
Rubén Díaz (outime) said :
#8

I'm the only developer here because the other (Marcos) left the
project. At this time I'm studying and working at the same time, so I
can't work as much as I want in Jisko, so any help would be
appreciated in order to improve the script.

On Sat, Aug 7, 2010 at 02:26, Andivista
<email address hidden> wrote:
> Question #120148 on Jisko changed:
> https://answers.launchpad.net/jisko/+question/120148
>
> Andivista posted a new comment:
> For deleting users i have written my own tool ( username, id,
> confirmation ) http://twitpic.com/2c97yj Spammers: Since more than 48
> hours i have no Spammers with my method :)
>
> --
> You received this question notification because you are an answer
> contact for Jisko.
>

--
Rubén Díaz
GPG id 2354DA5F
http://diazr.com
(+34) 644 46 93 64

Revision history for this message
Andivista (andi19642004) said :
#9

It is a pity that no more Marcos works at this fantastic project but i am sure he will have his reasons.

I work now about 1 week at your system 3.0RC1 ( test: toolbar4u.de/jisko/ ) but now it looks good. All what i want works fine.

Greetings from Berlin & Thx for Support
Andi ( andivista.com )

Revision history for this message
Michael (michael-lincme) said :
#10

@Andivista; Would you care to share how you changed it? Perhaps not publicly though (I don't know if it helps spammers). You can email me at lincme.co.uk if you like.

Also, would you share your member deletion code? I find it very irritating having spammers on the system - as I'm sure anyone does!

@Rubén; I think my only contributions at the moment are likely to be a theme, if anyone would want it, and updates to the EN_GB language file. I'll spend a little time on that now and then when I can. But if you can think of any other ways someone with only a little time to help can improve the project then please do say.

Also, is there an easy way to download the current project files? I'm on Windows Vista, and don't have any SVN tools.

Revision history for this message
Rubén Díaz (outime) said :
#11

You can download latest revision from http://svn.jisko.org/ :-)

On Sat, Aug 7, 2010 at 04:02, Michael
<email address hidden> wrote:
> Question #120148 on Jisko changed:
> https://answers.launchpad.net/jisko/+question/120148
>
> Michael posted a new comment:
> @Andivista; Would you care to share how you changed it? Perhaps not
> publicly though (I don't know if it helps spammers). You can email me at
> lincme.co.uk if you like.
>
> Also, would you share your member deletion code? I find it very
> irritating having spammers on the system - as I'm sure anyone does!
>
> @Rubén; I think my only contributions at the moment are likely to be a
> theme, if anyone would want it, and updates to the EN_GB language file.
> I'll spend a little time on that now and then when I can. But if you can
> think of any other ways someone with only a little time to help can
> improve the project then please do say.
>
> Also, is there an easy way to download the current project files? I'm on
> Windows Vista, and don't have any SVN tools.
>
> --
> You received this question notification because you are an answer
> contact for Jisko.
>

--
Rubén Díaz
GPG id 2354DA5F
http://diazr.com
(+34) 644 46 93 64

Revision history for this message
Andivista (andi19642004) said :
#12

@michael i send an e-mail

and here a simple standard database script modified by me for jisko ( http://www.php-kurs.com/mysql-datenbank-auslesen.htm )

<html>

<head>
<script type="text/javascript">

   function ask_first(link, question)
   {
    if (typeof(question) == 'undefined')
     question = 'really?'
    return window.confirm(question);
   }
  </script>
</head>
<body>

<?php
require_once ('your config file with database name, password etc.');

$id= $_GET["id"];
echo $id;
$db_link = mysql_connect (DB_HOST, DB_USER, DB_PASSWORD);

$db_sel = mysql_select_db( DB_NAME )
   or die("Auswahl der Datenbank fehlgeschlagen");

$sql = "SELECT * FROM users";

$db_erg = mysql_query( $sql );
if ( ! $db_erg )
{
  die('Ungültige Abfrage: ' . mysql_error());
}

echo '<table border="1">';
while ($zeile = mysql_fetch_array( $db_erg, MYSQL_ASSOC))
{
  echo "<tr>";
  echo "<td><a href=\"http://yourdomain.com/yourfile.php?id=" . $zeile['ID'] . "\" onclick=\"return ask_first(this);\">Delete user</a></td>";
  echo "<td>". $zeile['username'] . "</td>";
  echo "<td>". $zeile['status'] . "</td>";
  echo "</tr>";
}
$id= $_GET["id"];
$homepage = "/yourfile.php?id=$id";
$currentpage = $_SERVER['REQUEST_URI'];
if($homepage==$currentpage) {

$delete = 'DELETE FROM users WHERE ID='.$id.'';

$retval = mysql_query( $delete, $db_link );
if(! $retval )
{
  die('Could not delete data: ' . mysql_error());
}
echo "Deleted data successfully\n";

echo $sql;

}

echo "</table>";

mysql_free_result( $db_erg );

?>

<br />
<a href="http://youdomain.com/yourfile.php">Back</a>
<br />

</body>
</html>

Revision history for this message
Andivista (andi19642004) said :
#13

supplement!!! i put this file in an folder with .htaccess password protection

Revision history for this message
Andivista (andi19642004) said :
#14

with .htaccess folder ( http://www.javascriptkit.com/howto/htaccess3.shtml )

@Rubén could you delete the previous script? Thx

<html>

<head>
<script type="text/javascript">

   function ask_first(link, question)
   {
    if (typeof(question) == 'undefined')
     question = 'really?'
    return window.confirm(question);
   }
  </script>
</head>
<body>

<?php
require_once ('config file with database host, name, password ');

$id= $_GET["id"];
echo $id;
$db_link = mysql_connect (DB_HOST, DB_USER, DB_PASSWORD);

$db_sel = mysql_select_db( DB_NAME )
   or die("Auswahl der Datenbank fehlgeschlagen");

$sql = "SELECT * FROM users";

$db_erg = mysql_query( $sql );
if ( ! $db_erg )
{
  die('Ungültige Abfrage: ' . mysql_error());
}

echo '<table border="1">';
while ($zeile = mysql_fetch_array( $db_erg, MYSQL_ASSOC))
{
  echo "<tr>";
  echo "<td><a href=\"http://yourdomain.com/htacess_folder/yourfile.php?id=" . $zeile['ID'] . "\" onclick=\"return ask_first(this);\">Delete user</a></td>";
  echo "<td>". $zeile['username'] . "</td>";
  echo "<td>". $zeile['status'] . "</td>";
  echo "</tr>";
}
$id= $_GET["id"];
$homepage = "/htaccess_folder/yourfile.php?id=$id";
$currentpage = $_SERVER['REQUEST_URI'];
if($homepage==$currentpage) {

$delete = 'DELETE FROM users WHERE ID='.$id.'';

$retval = mysql_query( $delete, $db_link );
if(! $retval )
{
  die('Could not delete data: ' . mysql_error());
}
echo "Deleted data successfully\n";

echo $sql;

}

echo "</table>";

mysql_free_result( $db_erg );

?>

<br />
<a href="http://yourdomain.com/htaccess_folder/yourfile.php">Back</a>
<br />

</body>
</html>

Revision history for this message
Andivista (andi19642004) said :
#15

It is weekend, I have time and I wanted to have it easier. So i integrated the script in Jiskos Admin Panel ( include 'file.php'; ) :) I like Jisko http://twitpic.com/2cd6h2 But now I've made enough. Have a nice weekend!

Revision history for this message
Andivista (andi19642004) said :
#16

@michael

I have seen you have deletet the jisko system. You have written: Too many spammers were signing-up so we've changed to more secure software.

But there are so many scripts you could take for antispam

Like this http://identipic.com/ and many others

Here is the code for /themes/transparency/pages/register.php

<?php extract($_GET); global $allowed ?>

<?php if (!$allowed): ?>
<?php echo showStatus(__('You need a valid token to register an account'), 'error') ?>
<?php else: ?>

<div class="header_title"><?php t('Register') ?></div>

<?php if (!empty($openid)): ?>
<?php t("We couldn't find your OpenID url on our database, so maybe you want to register. To do so we need some details which you can fill in the form below") ?>
<br /><br /><br />
<?php elseif (!empty($fbid)): ?>
<?php t("We couldn't find your Facebook profile on our database, so maybe you want to register. To do so we need some details which you can fill in the form below") ?>
<br /><br /><br />
<?php endif; ?>
<form name="register" action="<?php anchor('register') ?>" method="post">
 <p><input name="token" type="hidden" value="<?php echo $token ?>" /></p>
 <p><?php t('Username') ?><br /><input name="username" type="text" class="input" value="<?php show($nickname) ?>" tabindex="1"/> </p>
 <p style="height:6px"></p>
 <p><?php t('E-mail') ?><br /><input name="email" type="text" class="input" value="<?php show($email) ?>" tabindex="2"/> </p>
 <p style="height:6px"></p>
 <?php if (empty($openid) && (empty($fbid))): ?>
 <div>
  <div style="float:right"><p style="margin-right:4px"><?php t('password (again)') ?><br /><input name="password2" type="password" class="input" value="" tabindex="4"/> </p></div>
  <p><?php t('Password') ?><br /><input name="password" type="password" class="input" value="" tabindex="3"/></p>
 </div>
 <?php endif; ?>
 <?php if (!empty($openid)): ?>
 <p style="height:6px"></p>
 <p><?php t('OpenID <strong>(optional)</strong>') ?>
 <br />
 <input name="openid" type="text" class="input" value="<?php show($openid) ?>" tabindex="5"/> </p>
 <?php endif; ?>
 <?php if (!empty($fbid)): ?>
 <input type="hidden" name="fbid" value="<?php show($fbid) ?>">
 <?php endif; ?>
 <p style="height:6px"></p>
 <p><?php t('Language') ?><br />

 <select name="language" id="lang" class="listbox" tabindex="5">
 <?php foreach (return_languages() as $short => $name): ?>
  <?php if (LANG == $short): ?>
  <option value="<?php echo $short ?>" selected ><?php echo $name ?></option>
  <?php else: ?>
  <option value="<?php echo $short ?>"><?php echo $name ?></option>
  <?php endif; ?>
 <?php endforeach; ?>
 </select> </p>

 <?php if (recaptcha_enabled()) echo '<br>'; load_recaptcha(); ?>
 <br />
 <?php if (tos_enabled()): ?>
 <p><input type="checkbox" name="legal" onclick="document.register.btregister.disabled=!document.register.btregister.disabled" /><?php t('I accept the') ?> <a href="<?php anchor('tos') ?>"><?php t('privacy and service terms') ?></a></p>
 <br />

 <table border="0">
<tr><td colspan="3">Security test. Please identify the pictures:</td></tr>
<tr><td><img src="http://yourdomain.com/identiPIC_1.jpg" alt=""></td><td><img src="http://yourdomain.com/identiPIC_2.jpg" alt=""></td><td><img src="http://yourdomain.com/identiPIC_3.jpg" alt=""></td></tr>
<tr><td>
<select name="identiPIC_selected[1]">
<option value="">Click to identify</option>

<option>Apple</option>
<option>Cat</option>
<option>Clock</option>
<option>Dog</option>
<option>Flower</option>
<option>Fork</option>
<option>Hammer</option>
<option>Key</option>
<option>Ship</option>

<option>Tree</option>
</select></td><td>

<select name="identiPIC_selected[2]">
<option value="">Click to identify</option>
<option>Apple</option>
<option>Cat</option>
<option>Clock</option>
<option>Dog</option>
<option>Flower</option>

<option>Fork</option>
<option>Hammer</option>
<option>Key</option>
<option>Ship</option>
<option>Tree</option>
</select></td><td>

<select name="identiPIC_selected[3]">
<option value="">Click to identify</option>
<option>Apple</option>

<option>Cat</option>
<option>Clock</option>
<option>Dog</option>
<option>Flower</option>
<option>Fork</option>
<option>Hammer</option>
<option>Key</option>
<option>Ship</option>
<option>Tree</option>

</select></td></tr></table>

 <p><input type="submit" name="btregister" value="<?php t('Register!') ?>" class="submit" disabled /></p>
 <?php else: ?>
 <p><input type="submit" name="btregister" value="<?php t('Register!') ?>" class="submit" /></p>
 <?php endif; ?>

and /pages register.php

<?php
// Jisko: An open-source microblogging application
// Copyright (C) 2008-10 Rubén Díaz <email address hidden>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

global $db;
global $_USER;
global $mailing, $jk;

if ($_USER) header('Location: '.$jk->base);
else {
 global $allowed, $sidebar;
 $sidebar = 'login';

 $allowed = check_invitation($_REQUEST['token']);

 if (!$_POST) {
  $jk->title = __('Register');

  $jk->load('functions');
  $jk->load('header');

  if ($_GET) {
   if (isset($_GET['ok'])) {
    if (!isEmailConfirmationEnabled()) {
     echo showStatus(__('Check your email (including SPAM) to activate your account'), 'ok');
    }
    else echo showStatus(__('You can access now with your account, thank you!'), 'ok');
   }
   elseif (($_GET['key']) and ($_GET['uid'])) {
    $result = $db->checkRegKey($_GET['key'], $_GET['uid']);
    if ($result) {
     echo showStatus(__('You can access now with your account, thank you!'), 'ok');
     $db->updateUserOptions($_GET['uid'], array('status' => 'ok'));
     $db->deleteKey($_GET['key'], $_GET['uid']);
     $userInfo = $db->getUserInfo($_GET['uid']);
     $mailing->registrationSuccess($userInfo['email'], $userInfo['ID']);
     if ($jk->alert_on_newuser == true) $mailing->alertNewUser($userInfo['username']);
    } else {
     echo showStatus(__('Invalid confirmation code!'), 'error');
    }
   }
  }
  if ($_GET['error']) {
   $error = $_GET['error'];

   switch ($error) {
    case 'invalidtoken':
     $error = __('You need a valid token to register an account!');
     break;
    case 'invalidmail':
     $error = __('Sorry! The provided email is invalid');
     break;
    case 'tos':
     $error = __('You must accept the Terms of Service (TOS)');
     break;
    case 'takenuser':
     $error = __('Taken username, please choose another!');
     break;
    case 'takenmail':
     $error = __('Email is taken, please choose another!');
     break;
    case 'pass':
     $error = __("Passwords don't match!");
     break;
    case 'recaptcha':
     $error = __('Incorrect reCAPTCHA code!');
     break;
    case 'user':
     $error = __("Sorry! Your choosen username appears to be invalid");
     break;
    case 'create':
     $error = __('There was a problem while trying to create your user');
     break;
   }

   if ($error) echo showStatus($error, 'error');
  }

  $jk->load('register');
  $jk->load('sidebar');
  $jk->load('footer');
 }
 else {
  if ($allowed) {
   global $mailing;

      if(!isset($_REQUEST['identiPIC_selected'])){exit;}

$identiPIC[1] = "Apple";
$identiPIC[2] = "Flower";
$identiPIC[3] = "Fork";

if($_REQUEST['identiPIC_selected'] !== $identiPIC){print "You have failed to identify the pictures correctly. Please try again."; exit;}
   $token = $_POST['token'];

   if (!check_invitation($token)) header('Location: '.coreLink(array('error=invalidtoken'), 'register'));
   else {
    if (!$_POST['legal'] && ($jk->tos == true)) header('Location: '.coreLink(array('error=tos'), 'register'));
    else {
     $username = $_POST['username'];
     $email = $_POST['email'];
     $salt = substr(md5(rand()), 0, 5);
     $api = substr(md5($_POST['username'].rand()), 0, 16);
     $password = md5(md5($_POST['password']).md5($salt));
     $password2 = md5(md5($_POST['password2']).md5($salt));
     $ip = $_SERVER['REMOTE_ADDR'];
     $language = $_POST['language'];

     if ($_POST['openid']) {
      if (filter_var($_POST['openid'], FILTER_VALIDATE_URL)) {
       if (!$db->checkOpenID($_POST['openid'])) {
        import('openid/functions');
        import('openid/class.dopeopenid');
        $openid = new Dope_OpenID($_POST['openid']);
        $openid->setReturnURL($jk->base);
        $openid->SetTrustRoot($jk->base);
        $openid->setOptionalInfo(array('nickname', 'language', 'email'));
        $endpoint_url = $openid->getOpenIDEndpoint();
        if ($endpoint_url) $openidz = $openid->getIdentity();
        else $openidz = false;
       }
      }
      else $openidz = false;
     }
     else $openidz = false;
     if ($_POST['fbid']) {
      if (!empty($_POST['fbid'])) {
       if (!$db->checkFacebook($_POST['fbid'])) $fbidz = $_POST['fbid'];
       else $fbidz = false;
      }
      else $fbidz = false;
     }
     else $fbidz = false;

     if (!isEmailConfirmationEnabled()) $noc = false; else $noc = true;
     if (recaptcha_enabled()) $human = recaptcha_check_answer($jk->recaptcha_privatekey, $ip, $_POST['recaptcha_challenge_field'], $_POST['recaptcha_response_field']);

     $validUsr = validUsername($username, true);

     if ($validUsr != 'valid') {
      if ($validUsr == 'busy') header('Location: '.coreLink(array('error=takenuser'), 'register'));
      elseif ($validUsr == 'invalid') header('Location: '.coreLink(array('error=user'), 'register'));
     }
     else {
      if ($db->checkEmail($email)) header('Location: '.coreLink(array('error=takenmail'), 'register'));
      else {
       if (!$fbidz && !$openidz && ($password != $password2)) header('Location: '.coreLink(array('error=pass'), 'register'));
       else {
        if (recaptcha_enabled() && !$human->is_valid) header('Location: '.coreLink(array('error=recaptcha'), 'register'));
        else {
         if (!filter_var($email, FILTER_VALIDATE_EMAIL)) header('Location: '.coreLink(array('error=invalidmail'), 'register'));
         else {
          if (!mkdir(PATH."users_files/$username", 0777) || (!mkdir(PATH."users_files/$username/img", 0777) || (!mkdir(PATH."users_files/$username/img/avatar", 0777) || (!mkdir(PATH."users_files/$username/img/background", 0777) || (!mkdir(PATH."users_files/$username/files", 0777)))))) {
           header('Location: '.coreLink(array('error=create'), 'register'));
          }
          else {
           $tmpKey = substr(md5(rand()), 0, 6);

           if ($fbidz || ($openidz)) $password = '';

           $newUser = $db->newUser(
            $username,
            $password,
            $api,
            $salt,
            $language,
            $jk->default_theme,
            $email,
            $ip,
            $tmpKey,
            $noc,
            $openidz,
            $fbidz
           );

           if (!empty($token)) $db->deleteToken($token);

           if ($noc == false) {
            $mailing->confirmRegistration($email, $newUser, $tmpKey);
           }

           header('Location: '.coreLink(array('ok'), 'register'));
          }
         }
        }
       }
      }
     }
    }
   }
  }
  else {
   header('Location: '.coreLink(array('error=invalidtoken'), 'register'));
  }
 }
}

?>

</form>
<div class="separator"></div>

<?php endif; ?>

Greetings from Berlin
Andi

Revision history for this message
Michael (michael-lincme) said :
#17

@Andivista - Thanks for the ideas and code. I've changed a couple of sites I work on to Vanilla 2, as it allows for more in-depth discussion, also has an 'activity wall', and more. The anti-spam functions in it work, and deleting users provides options to reassign or delete posted content, etc. All in all, a more useful system, and no more time and effort required. Jisko is very good, but needs a lot of time and effort spending on it to make it really cool. It's looking like an abandoned project now, which is a shame.