Page 1 of 3

[ABD] Anti-Registration-Spammers

Posted: Thu Oct 14, 2004 5:25 pm
by drathbun
Why this MOD?
You may have seen members signing up for your forum and not posting. They are signing up simply to spam your registration / memberlist, and get a back-link from their member profile. To use the following code I suggest that you set your user activation to User or Admin in your control panel. Otherwise all registrations are automatically "active" even with bogus email addresses.

phpBB Version Information
Code change tested with 2.10 only. Earlier versions may ask... try it yourself and see. Please do not ask me if it works for earlier versions.

Description
This code is a possible alternative to the visual confirmation mod. This mod does not require you have the gd library available on your server. In a nutshell, this mod:
  • Shows only "active" members on your memberlist
  • Shows only "active" members as the "newest member" on your index page
  • Prevents guests from viewing your memberlist
  • Prevents members with fewer than 30 posts from viewing your memberlist
  • Does not show a website for any member with fewer than 30 posts
  • Does not allow a member to enter a website during the registration process
  • Does not allow a member to update their profile with a website until they have posted 30 times or more
This code was written because I removed the capability to enter a website during a registration, yet spam-bots were still getting through. The code, as written here, has been in use on my board for over a month now and no spammers are getting through. Of course I make no guarantees, but it has worked for me so far. Many of the parts of this mod are optional (you do not, for example, have to hide your memberlist from non-members in order to use the anti-registration spammer code) and are noted in the instructions below.


MOD Version 0.5
This code has been well tested on my board, but it may not work in all cases. Back up all files before installing this MOD. Note that I do not plan to offer update scripts for this MOD. As I complete the "to do" list below prior to releasing this MOD I will simply be updating the install notes. If you are not comfortable with that, then do not install the code at this time. You have been warned. :-)

To Do
Make proper language entries
Make the "30" post limit an option in the ACP
Use the proper MOD template

Begin MOD instructions
This change makes it so that only registered members can view your memberlist. If left out, anyone browsing your forum can view the memberlist. (Optional) The last portion of this inserted block of code can be left out... if left in, then only registered members with more than 30 posts can view the memberlist.
open

Code: Select all

memberlist.php
find

Code: Select all

init_userprefs($userdata);
//
// End session management
//
After, add

Code: Select all

// Require user to be logged in to view the memberlist
if ( ! ($userdata['session_logged_in'] ))
{
        $header_location = ( @preg_match('/Microsoft|WebSTAR|Xitami/', getenv('SERVER_SOFTWARE')) ) ? 'Refresh: 0; URL=' : 'Location: ';
        header($header_location . append_sid("login.$phpEx?redirect=memberlist.$phpEx&", true));
        exit;
}
// end user logged in memberlist mod
// only allow viewing of memberlist for members with more
// then 30 posts (optional)
if ($userdata['user_posts'] < 30)
{
        message_die(GENERAL_ERROR, 'You are not authorized to view the memberlist until you have participated more in the forums.');
}
This change makes it so that a member has to have 30 or more posts before their website (if any) is displayed on their member listing. Admins will always see the web site.
find

Code: Select all

                $www_img = ( $row['user_website'] ) ? '<a href="' . $row['user_website'] . '" target="_userwww"><img src="' . $images['icon_www'] . '" alt="' . $lang['Visit_website'] . '" title="' . $lang['Visit_website'] . '" border="0" /></a>' : '';
                $www = ( $row['user_website'] ) ? '<a href="' . $row['user_website'] . '" target="_userwww">' . $lang['Visit_website'] . '</a>' : '';
Replace with

Code: Select all

                if ( ($row['user_posts'] < 30) && ($userdata['user_level'] != ADMIN))
                {
                        $www_img = '';
                        $www = '';
                }
                else
                {
                $www_img = ( $row['user_website'] ) ? '<a href="' . $row['user_website'] . '" target="_userwww"><img src="' . $images['icon_www'] . '" alt="' . $lang['Visit_website'] . '" title="' . $lang['Visit_website'] . '" border="0" /></a>' : '';
                $www = ( $row['user_website'] ) ? '<a href="' . $row['user_website'] . '" target="_userwww">' . $lang['Visit_website'] . '</a>' : '';
                }
This change ensures that only active members are shown on the memberlist. Inactive members are invisible. (Optional step)
find

Code: Select all

        FROM " . USERS_TABLE . "
        WHERE user_id <> " . ANONYMOUS . "
After, add

Code: Select all

        AND     user_active = 1
If you are not going to display inactive members on your memberlist then you probably don't want to display them as the "newest member" on the index page either. This change does that.
open includes/functions.php
find

Code: Select all

                case 'newestuser':
                        $sql = "SELECT user_id, username
                                FROM " . USERS_TABLE . "
                                WHERE user_id <> " . ANONYMOUS . "
After, add

Code: Select all

                                AND user_active = 1
The next section prevents users from filling out a website until they have 30 or more posts. It also denies registrations to "bots" that are sending in registration data without using your form. Since the web site is not a visible field, anyone that includes website data during a registration is a bot and is denied. Be as rude as you want with the denial message; normal users won't see it. :-)
open

Code: Select all

includes/usercp_register.php
find

Code: Select all

        while( list($var, $param) = @each($strip_var_list) )
        {
                if ( !empty($HTTP_POST_VARS[$param]) )
                {
                        $$var = trim(strip_tags($HTTP_POST_VARS[$param]));
                }
        }
After, add

Code: Select all

        if (isset($website) && ($mode == 'register'))
        {
                message_die (GENERAL_MESSAGE, 'Registration Attempt Ignored');
        }
find

Code: Select all

        $website = $userdata['user_website'];
replace with

Code: Select all

        if ($userdata['user_posts'] >= 30)
        {
                $website = htmlspecialchars($userdata['user_website']);
        }
        else
        {
                $website = '';
        }
The next step is repeated twice... there are two lines that are exactly the same, find and replace both.
find

Code: Select all

                $website = stripslashes($website);
Replace with

Code: Select all

        if ($userdata['user_posts'] >= 30)
        {
                $website = htmlspecialchars(stripslashes($website));
        }
        else
        {
                $website = '';
        }
find

Code: Select all

                'S_PROFILE_ACTION' => append_sid("profile.$phpEx"))
        );
After, add

Code: Select all

        if ($userdata['user_posts'] >= 30)
        {

                $template->assign_block_vars('switch_website', array() );

        }
Set up switch in the profile "edit" template to allow user to add / edit their website only after restrictions have been met.
open

Code: Select all

templates/subSilver/profile_add_body.tpl
Find

Code: Select all

        <tr>
          <td class="row1"><span class="gen">{L_WEBSITE}:</span></td>
          <td class="row2">
                <input type="text" class="post"style="width: 200px"  name="website" size="25" maxlength="255" value="{WEBSITE}" />
          </td>
        </tr>
Replace with

Code: Select all

        <!-- BEGIN switch_website -->
        <tr>
          <td class="row1"><span class="gen">{L_WEBSITE}:</span></td>
          <td class="row2">
                <input type="text" class="post"style="width: 200px"  name="website" size="25" maxlength="255" value="{WEBSITE}" />
          </td>
        </tr>
        <!-- END switch_website -->
Set up template switch so that use website is only displayed (viewed) if certain conditions are met.
open

Code: Select all

templates/subSilver/profile_view_body.tpl
find

Code: Select all

                <tr>
                  <td valign="middle" align="right" nowrap="nowrap"><span class="gen">{L_WEBSITE}:&</span></td>
                  <td><span class="gen"><b>{WWW}</b></span></td>
                </tr>
Replace with

Code: Select all

                <!-- BEGIN switch_website -->
                <tr>
                  <td valign="middle" align="right" nowrap="nowrap"><span class="gen">{L_WEBSITE}:&</span></td>
                  <td><span class="gen"><b>{WWW}</b></span></td>
                </tr>
                <!-- END switch_website -->
open

Code: Select all

includes/usercp_viewprofile.php
find

Code: Select all

$www_img = ( $profiledata['user_website'] ) ? '<a href="' . $profiledata['user_website'] . '" target="_userwww"><img src="' . $images['icon_www'] . '" alt="' . $lang['Visit_website'] . '" title="' . $lang['Visit_website'] . '" border="0" /></a>' : '&nbsp;';
Before, add

Code: Select all

if ( ($profiledata['user_posts'] > 30) || ($userdata['user_level'] == ADMIN) )
{
        $template->assign_block_vars('switch_website', array() );
}
open

Code: Select all

viewtopic.php
find

Code: Select all

                $www_img = ( $postrow[$i]['user_website'] ) ? '<a href="' . $postrow[$i]['user_website'] . '" target="_userwww"><img src="' . $images['icon_www'] . '" alt="' . $lang['Visit_website'] . '" title="' . $lang['Visit_website'] . '" border="0" /></a>' : '';
                $www = ( $postrow[$i]['user_website'] ) ? '<a href="' . $postrow[$i]['user_website'] . '" target="_userwww">' . $lang['Visit_website'] . '</a>' : '';
Replace with

Code: Select all

                if (($postrow[$i]['user_posts'] < 30) && ($userdata['user_level'] != ADMIN))
                {
                        $www_img = '';
                        $www = '';
                }
                else
                {
                        $www_img = ( $postrow[$i]['user_website'] ) ? '<a href="' . $postrow[$i]['user_website'] . '" target="_userwww"><img src="' . $images['icon_www'] . '" alt="' . $lang['Visit_website'] . '" title="' . $lang['Visit_website'] . '" border="0" /></a>' : '';
                        $www = ( $postrow[$i]['user_website'] ) ? '<a href="' . $postrow[$i]['user_website'] . '" target="_userwww">' . $lang['Visit_website'] . '</a>' : '';
                }

Posted: Sat Oct 23, 2004 4:17 am
by drathbun
I thought that there would be more interest in this, as this seems to be a "hot button" item at the moment. However, there are other anti-registration spammer MODs in Beta, so I am considering dropping mine for lack of interest. It's working for me, but I'm not going to take the time to complete the "to do" list if nobody else is interested in it.

I'm not whining... :-) If nobody else is interested, that's easier for me. More time to do something else interesting.

For the record, some other anti-registration spammer tactics can be found in the following topics:

This one checks for spam-like behavior and then not only prevents the registration but bans the offender. I'm a bit wary of the banning part, but here's the link:
http://www.phpbb.com/phpBB/viewtopic.php?t=186683

Here's a link to a simple check that I think would be difficult to maintain over the long run, but it may be easier for folks that are not excited about the amount of editing required for my MOD. This topic shows how to simply provide a list of websites that will cause the registration attempt to be ignored:
http://www.phpbb.com/phpBB/viewtopic.php?t=234090

There is also, of course, the visual confirmation MOD.

Bottom line is that there are already a number of alternatives, all of which are getting more attention than this topic.

Posted: Sat Oct 23, 2004 7:41 am
by reddog
It would be better to make a file of installation :wink:

So, it's nice.

++

Posted: Sat Oct 23, 2004 11:43 am
by reddog
I noticed that the field is visible during the registration. I modified so that it is invisible.

open includes/usercp_register.php

Find

Code: Select all

		'S_PROFILE_ACTION' => append_sid("profile.$phpEx"))
	);
After add

Code: Select all

        if ($userdata['user_posts'] >= 10 && ($mode != 'register'))
        {

                $template->assign_block_vars('switch_website', array() );

        }
ps: I have reduce the minimum number of posts to 10 in my example. Otherwise, the modification seems to work.

Posted: Sat Oct 23, 2004 3:01 pm
by drathbun
reddog wrote: I noticed that the field is visible during the registration. I modified so that it is invisible.

That code is already there... :?

Posted: Fri Nov 12, 2004 6:15 pm
by drathbun
FWIW, it has been over a month since I implemented this on my board, and I've had exactly zero bogus / spammer registrations. I have had some registrations by actual humans that were bogus or spammers :-) but they actually posted. Given that it appears to be working (at least until the spam-bots get more creative) I will write this up using the MOD template and provide a download link shortly.

Posted: Mon Nov 15, 2004 9:08 am
by davidh44
drathbun wrote: I will write this up using the MOD template and provide a download link shortly.


Thanks drathbun, looking forward to it!

Posted: Wed Nov 17, 2004 9:49 am
by macgeek
Hey! The MOD works great!

One suggestion... Would it be possible to allow other administrators and moderators to look at the membership list, even if they have less than 30 posts? I'm thinking about using an administrator account strictly for administrative purposes. I don't want to use it to post anything, therefore the account will always be 0 posts.

--- macgeek

Posted: Mon Feb 21, 2005 3:54 pm
by Einstein
Great MOD ... I like it. I only implemented the user_active=1 on my forum. I think its enough to keep the spam bots away. Later on you can delete the database with unactiveted users.

I don't really like the website restrictions. I haven't seen yet seen a bot that can activate itself.

And thank you ...

Posted: Tue Feb 22, 2005 7:56 pm
by Einstein
Einstein wrote: I haven't seen yet seen a bot that can activate itself.

Now, I have :x

Time to install the visual confirmation?

Posted: Wed Jun 29, 2005 9:06 pm
by NightSpirit
Have just installed this mod (well 90% of it) on my site along with some other changes. We've been getting annoying bogus spam/script signups even with visual confirmation turned on :( This mod should help fix this :)

Posted: Wed Jun 29, 2005 11:20 pm
by drathbun
It's still on my list to write up. Just have other things to finish first.

Posted: Sat Jan 21, 2006 1:57 pm
by krijgsman
This mod is great. I already had some parts of these hacks done myself but I followed these instructions to add some extra layers of security.

[edit] Forget my first reaction, something else is causing this mod to fail. Going to figure out what it is.[/edit]

Posted: Sat Jan 21, 2006 2:23 pm
by drathbun
Wow, forgot about this one. Let me know if you find out what caused your install to fail, and I'll see about helping with a fix.

Posted: Sat Jan 21, 2006 5:26 pm
by krijgsman
There are several mods for this going around but this is the first one I found with a fairly good howto.

It conflicts with other mods that add "<!-- switch" options to templates/subSilver/profile_add_body.tpl Please note that the "<!-- switch_website" must not be within any other "<!-- switch" option or it will not work.

Making the language within the language/ tree is fairly simple can shouldn't be a problem for anybody who had done ths before.
If you want an option in the ACP, change all occurences of "30" into "$board_config['anti_spam_posts']" and follow the instructions below:



open admin/admin_board.php

find

Code: Select all

"L_SUBMIT" => $lang['Submit'],
before, add

Code: Select all

"L_ANTI_SPAM_POSTS" => $lang['anti_spam_posts'],
"L_ANTI_SPAM_POSTS_EXPLAIN" => $lang['anti_spam_posts_explain'],
find

Code: Select all

"SMTP_PASSWORD" => $new['smtp_password'],
after, add

Code: Select all

"ANTI_SPAM_POSTS" => $new['anti_spam_posts'],

Open templates/subSilver/admin/board_config_body.tpl

find

Code: Select all

<tr>
                <td class="row1">{L_TOPICS_PER_PAGE}</td>
before, add

Code: Select all

<tr>
                <td class="row1">{L_ANTI_SPAM_POSTS}<br /><span class="gensmall">{L_ANTI_SPAM_POSTS_EXPLAIN}</span></td>
                <td class="row2"><input class="post" type="text" size="3" maxlength="4" name="anti_spam_posts" value="{ANTI_SPAM_POSTS}" /></td>
</tr>

open language/lang_english/lang_admin.php

find

Code: Select all

//
// That's all Folks!
// -------------------------------------------------
before, add

Code: Select all

// Anti-registration spammers
$lang['anti_spam_posts'] = 'Anti-spam posts limit';
$lang['anti_spam_posts_explain'] = 'Amount of posts a user must have before allowed to add a website link in the profile (0 disables this option).';

This little hack should stop many, if not all, auto-registration bots out there. Since the purpose of those bots are to get as much links to a website there is no need for them to change their script to not include the website field and thus bypass the security. Doing that will only nullify the reason why they wanted to register in the first place.