PhpBB3 MOD: phpBB spam hammer

From DP

Jump to: navigation , search

This MOD for the phpBB3 forum stops almost all spam by disabling links and bad words in posts, messages, signatures, and profiles until new users reach a certain number of posts and/or age.

Contents

Features

Phpbb-disablelinks-tooshort-.pngLink-filter-zombiecleanup.pngSpam-hammer-acp.pngLink-filter-pm.pngLink-filter-post.pngLink-filter-profile.pngLink-filter-signature.png

  • Disables links and bad words in posts, messages, signatures, and profiles until a user reaches a specified age and/or number of posts
  • Own-site links are excluded from the filter, other sites can be added to a whitelist
  • Configurable list of forbidden filter words, optionally show the user the trigger term
  • Configurable unicode filters to prevent spam in languages not used in the forum
  • Prevents 'sleeper agents' by disabling posts, signatures, and profiles for old accounts with 0 posts (optional)
  • Zombie registration cleanup deletes old users with no posts (optional)
  • Protections are 'automatically' disabled after the criteria are met (no moderation required)

History:

AUTOMOD

Thanks to Philthy there is now a phpBB3 AUTOMOD version of spam hammer.

AUTOMOD ISSUES

There are two minor automod issues, both are harmless.

SQL ERRORS ON UNINSTALL

  • Several empty SQL errors on uninstall.

I googled but didn't see how to fix it via automod. You can:

  1. Force uninstall anyways, it will just leave the settings in the database and they will be ignored.
  2. Force uninstall and then go to phpmysql, etc, and delete the entries.

SQL ERRORS ON RE-INSTALL

  • Duplicate entry errors on re-install

Related to above error: the entries are still in the settings database. You can:

  1. Force the install, your previous settings will be restored.

phpBB3 MOD configuration

How to configure the phpBB3 MOD.

Setting are found in General->Post settings

Minimum post count

Minimum number of posts a user must make before they can use links. Users will need this number of posts before they are able to use the [URL] BBCode tag or post external page urls and domain references. Applies to posts, signatures, PMs, and profiles.

  • Enter 0 to disable check
  • This AND the minimum days registered must be met
  • Recommended setting: 1 post

Minimum days registered

Minimum number of days the account must be registered to post links. Users will need to have registered this many days before they are able to use the [URL] BBCode tag or post external page urls and domain references. Applies to posts, signatures, PMs, and profiles.

  • Enter 0 to disable age check
  • This AND the minimum number of posts must be met
  • Recommended setting: 1 day

Disable sleeper agents

Disable posting, signature, and profiles for new users with 0 posts after minimum days (above). Prevents old accounts from coming back as spammers.

Antispam: account disabled, please contact an admin.

phpBB3 MOD error message.

User with 0 posts after minimum account age will be prohibited from posting, signatures, and profiles.

What is this about? We ban links based on age and posts, but imagine a spammer script that:

  1. Registers a bunch of accounts on one day
  2. Comes back after the minimum account age
  3. Posts the minimum account posts until the filter is off
  4. Then blasts the forum full of spam

All that could happen before you have a chance to see and delete the initial posts.

The sleeper agent check stops this. If the new user has not posted an initial post within the minimum account age windows, then posting, signatures, and profiles are disabled and an error is displayed.

Private messages remain active (with filters enabled) so the user can contact an admin.

Most of our members join and post right away, so this is transparent to almost everyone.

There is no real way to get a user out of this state.
Delete them and let them register again, or disable sleeper check.

Minimum first and guest post chars

First post and guest post must be at least this many characters. 0 to disable.

  Sorry, your first post needs to be just a little longer.

phpBB3 MOD error message.

Some scripts are so stupid they don't know they have no signature spam and post little "ego posts" anyways. This requires the first post to be this many characters or longer. In the long run this is could lead to longer first posts, but that will also make the spammer more obvious (or they have to make a real contribution to go unnoticed).

  • Enter 0 to disable check
  • Only applies to the first post, not every post until the filter is disabled
  • Always applied to guest posts
  • Recommended stetting: 73 (light touch, less is more, it should go unnoticed by new users)

Link search strings

Anything in this line is considered a link and cannot be posted by a new user.

Our recommended link string (v03):

  • http://,www.,.com,.net,.org,.uk,.ly,.me,.ru,.biz,.info,dot com,dot net,dot org,dotcom,dotnet,dotorg,_com,_org,_co_uk,_ru,dot ru

Bad word search strings

Words on this list are not allowed, an error is shown.

We recommend only obvious words taken from past spams. Less (20 or so) is more.

Link whitelist

In addition to links at the same site as the forum, new users can also posts links to these sites.

Links at the same site as the forum are automatically allowed. Additional URLs to ignore can be added here.

Unicode REGEX filter

Some spam is in a language not used on the site. This box is for a regular expression that searches for unicode character ranges. Unicode character are usually non-english letters. For example Cyrillic. If the post contains these characters an error is shown.

  • The box is for any full PHP REGEX you'd like to use on posts
  • Requires a full PHP PREG_MATCH style REGEX filter (see examples below)
  • Leave blank to disable this feature
  • Unicode block reference

Example ranges

 /([\x{0400}-\x{04FF}]|[\x{0600}-\x{06FF}])+/u

Here is an example REGEX to enter in the phpBB MOD ACP:

  • This example is for Cyrillic (0400-04FF) and Arabic (0600-06FF)
  • You need to include the / at the beginning
  • You need to include the /+u at the end
 /([\x{0400}-\x{04FF}]|[\x{0600}-\x{06FF}]|[\x{3100}-\x{312f}])+/u

Add the Mandarin Bopomofo block (Chinese characters) to the first REGEX like this.

Non-unicode threshold

What percent of a post must be non-unicode characters. Enter as 0.95 for 95%, leave blank to disable.

There is a secondary unicode filter that simply tests for all unicode characters. This is probably best for English and similar language sites only. If your language uses unicode, consider blocking unused ranges with the filter above.

The value represents the percent of post that must be non-unicode. For example 0.95 means that 95% of the post must be non-unicode or an error is displayed.

Filter help link

A link to a post that explains the filter criteria. Leave blank to disable.

A user might want to know why and how long their account is restricted. It's a good idea to write a forum post explaining the limits. If a URL is entered on this line it will be displayed with 'click for help' in the error message.

This forum is protected by [url=http://dangerousprototypes.com/docs/PhpBB3_MOD:_Disable_links_for_new_users]phpBB3 spam hammer[/url]. Here's how our simple anti-spam measures work.

[b]These restrictions only apply to new users. They are removed automatically after your account meets certain criteria. Normal users will never be effected by these restrictions.[/b]

Spam poured in after our recent move to a phpBB forum. Captchas, registration questions, and other measures only stopped the stupidest scripts and annoyed everyone. Instead, we stopped spammers from getting what they want - new members can't post links. This method that has stopped 100% of spam so far, and it is totally transparent to most people.

[b]How does it work?[/b]
New user accounts are slightly restricted to deny spammers a place to put a link.

[i]These restrictions only apply to new users. They are removed automatically after your account meets certain criteria. Normal users will never be effected by these restrictions.[/i]

1. New users receive an error if they use off-site links in posts or signatures. New users can still link to dangerousprototypes.com, and a select set of white-list sites like Google Code, distributors, etc.
2. New users receive an error if they use certain forbidden words in posts or signatures. The error reports the trigger word to help you find and remove it.
3. New users receive an error if they enter non-English characters (like Cyrillic).
4. New users can't save a personal profile. Spammers like to put a URL in the personal profile.
5. Accounts that don't post within 24 hours of registration are automatically disabled and then purged. We get 100s of zombie spam registrations every day, an automated process cleans them out.

[b]Who is a new user?[/b]
The above restrictions only apply to new users. We are constantly tweaking the definition of a new user to stop spam while not annoying real people. These restrictions currently apply to users who:
*Have less than 1 post
*Registered in the last 24 hours
The restrictions are automatically removed once an account meets these criteria.

[b]Warning!! Extreme honey-pot mode in use!![/b]
Users with 0 posts will be automatically deleted for certain common spam behaviors:
*Entering a profile
*Entering a signature with external links
*Entering more than 20 links in the first post

[b]Help, I'm stuck[/b]
I apologize if you get caught in the filter. We'll keep tweaking it to find a good balance of usability.

Log filter activity

Logs all filter activity to system log. Not recommended.

Enables verbose event logging to the phpBB3 user and admin logs.

Wed Feb 23, 2011 5:09 pm {Spam hammer: deleted MeredithKM for profile abuse.}
Wed Feb 23, 2011 5:09 pm {Spam hammer: CHECKED PROFILE of 'MeredithKM'. DETECTED: profile disabled, ERRORS: Antispam: You can't have a profile yet. You need to post a few times first. Click for help.}
Wed Feb 23, 2011 5:07 pm {Spam hammer: deleted TimyrPlaipsy for profile abuse.}
Wed Feb 23, 2011 5:07 pm {Spam hammer: CHECKED PROFILE of 'TimyrPlaipsy'. DETECTED: profile disabled, ERRORS: Antispam: You can't have a profile yet. You need to post a few times first. Click for help.}
Wed Feb 23, 2011 5:03 pm {Spam hammer: CHECKED POST of 'Anonymous'. DETECTED: links, bad words, ERRORS: Your post looks too spamy for a new user, please remove off-site URLs. Click for help., Your post looks too spamy for a new user, please remove bad words or non-english text. (porn) Click for help. CONTENTS: порнофильм данилова.......HUGE LINK LIST REMOVED......}

Example log.

Zombie registration purge

Purges users with 0 posts after the number of days set in Days before zombie purge. Purge happens automatically once each day.

We get 100s of script registrations every day. Captchas, challenge questions, and other stuff only stops the stupidest scripts, and annoys users. We forbid them from posting links, but that doesn't stop them from registering.

The zombie registration purge deletes all users with 0 posts who are older than the Days before zombie purge: setting.

Extreme mode

This MOD has a few honeypot features that attempt to attract and auto-delete spammers.

Users with 0 posts are deleted if they:

  • Submit a profile
  • Submit a spammy signature
  • Use tons of links in their first post

Enable extreme mode

Extreme mode must be enabled in the source code:

  1. Install the MOD
  2. Open /includes/functions_link_filter.php with a text editor
  3. Find private $extreme=false;
  4. Change to private $extreme=true;
  5. Save and replace the file
private $extreme_links_delete=9;

This additional setting configures the max number of links in a first post. Users are automatically deleted if they submit more links in their first post.

Users are returned to the post with an error so they can copy and paste the post for later if it was legit.

Class overview

This currently shows the variable in the class and documents what they do.

No link strings

// An array of no-nos. Add whatever you need...
private $no_link_strings=array();

This list is used to search for links. Update it as needed.

Our recommended link string (v03):

  • http://,www.,.com,.net,.org,.uk,.ly,.me,.ru,.biz,.info,dot com,dot net,dot org,dotcom,dotnet,dotorg,_com,_org,_co_uk,_ru,dot ru

No word strings

//a secondary spam words filter
private $no_word_strings=array();

Words on this list are not allowed, an error is shown. We recommend only obvious words taken from past spams. Less (20 or so) is more.

private $show_trigger_word=true;

If true the user is shown the word that caused the error. Recommended because the filter is not smart and will match inside another word (think scum).

Whitelist URLs

//URLS to ALLOW always. In addition to own-site urls
private $whitelist_urls=array();

Links at the same site as the forum are automatically allowed. Additional URLs to ignore can be added here.

$whitelist_urls=array('http://code.google.com', 'http://sourceforge.net',);

This allows links to Google Code and Sourceforge, common sites we use in this forum.

Unicode range filter

private $unicode_filter='/([\x{0400}-\x{04FF}])+/u';

Some spam is in a language not used on the site. This is a regular expression that searches for unicode character ranges. Unicode are the letter sets used for non-english standard characters. For example Cyrillic. If the post contains these characters an error is shown.

  • Requires a full PHP PREG_MATCH style REGEX filter (see examples below)
  • Leave blank to disable this feature
  • Unicode block reference

Example ranges

$unicode_filter='/([\x{0400}-\x{04FF}]|[\x{0600}-\x{06FF}]|[\x{3100}-\x{312F}])+/u';

Example of chaining together multiple filter blocks. REGEX does the chaining of multiple character sets itself, so it's not quite like the search terms and URL elements. PREG_MATCH evaluates the whole statement at one time.

REGEX in phpBB MOD

 /([\x{0400}-\x{04FF}]|[\x{0600}-\x{06FF}])+/u

Here is an example REGEX to enter in the phpBB MOD ACP:

  • You need to include the / at the beginning
  • You need to include the /+u at the end
  • The box is for any full PHP REGEX you'd like to use on your posts
  • This example is for Cyrillic (0400-04FF) and Arabic (0600-06FF)
/([\x{0400}-\x{04FF}]|[\x{0600}-\x{06FF}]|[\x{3100}-\x{312f}])+/u

Add the Mandarin Bopomofo block (Chinese characters) to the first REGEX like this.

Unicode percent filter

private $minimum_nonunicode_text=0.95;

There is a secondary unicode filter that simply tests for all unicode character. This is probably best for English and similar language sites only. If your language uses unicode consider blocking unused ranges with the filter above.

The value represents the percent of post that must be non-unicode. For example 0.95 means that 95% of the post must be non-unicode or an error is displayed.

Help URL

private $help_url = 'http://da....';

A user might want to know why and how long their account is restricted. It's a good idea to write a forum post explaining the limits. If a URL is entered on this line it will be displayed with 'click for help' in the error message.

Load from database

private $load_values_from_db=false; //enable to use with DB, or use the values below

The settings can cpme from the database values for the disable links plugin, or frpm the settings in the class. Set to true to use database settings.

Minimum account age

private $minimum_days=1;

Minimum number of days the account must be registered to post links.

  • Enter 0 to disable age check
  • This AND the minimum number of posts must be met
  • Recommended setting: 1 day

Minimum account posts

private $minimum_posts=1; //minimum posts for member to post links

Minimum number of posts a user must make before they can use links.

  • Enter 0 to disable check
  • This AND the minimum account age must be met
  • Recommended setting: 1 post

Minimum first post length

Sorry, your first post needs to be just a little longer.

phpBB3 MOD error message.

private $first_post_length=73;//a minimum characters for the first post. enter 0 to disable

Some scripts are so stupid they don't know they have no signature spam and post little "ego posts" anyways. This requires the first post to be this many characters or longer. In the long run this is could lead to longer first posts, but that will also make the spammer more obvious (or they have to make a real contribution to go unnoticed).

  • Enter 0 to disable check
  • Only applies to the first post, not every post until the filter is disabled
  • Always applied to guest posts
  • Recommended stetting: 73 (light touch, less is more, it should go unnoticed by new users)

Sleeper agent check

Antispam: account disabled, please contact an admin.

phpBB3 MOD error message.

private $sleeper_check=true;

User with 0 posts after minimum account age will be prohibited from posting, signatures, and profiles.


What is this about? We ban links based on age and posts, but imagine a spammer script that:

  1. Registers a bunch of accounts on one day
  2. Comes back after the minimum account age
  3. Posts the minimum account posts until the filter is off
  4. Then blasts the forum full of spam

All that could happen before you have a chance to see and delete the initial posts.

The sleeper agent check stops this. If the new user has not posted an initial post within the minimum account age windows, then posting, signatures, and profiles are disabled and an error is displayed.

Private messages remain active (with filters enabled) so the user can contact an admin.

Most of our members join and post right away, so this is transparent to almost everyone.

There is no real way to get a user out of this state. Delete them and let them register again.

Logging

private $log_activity

Enables verbose event logging to the phpBB3 user and admin logs.

Wed Feb 23, 2011 5:09 pm {Spam hammer: deleted MeredithKM for profile abuse.}
Wed Feb 23, 2011 5:09 pm {Spam hammer: CHECKED PROFILE of 'MeredithKM'. DETECTED: profile disabled, ERRORS: Antispam: You can't have a profile yet. You need to post a few times first. Click for help.}
Wed Feb 23, 2011 5:07 pm {Spam hammer: deleted TimyrPlaipsy for profile abuse.}
Wed Feb 23, 2011 5:07 pm {Spam hammer: CHECKED PROFILE of 'TimyrPlaipsy'. DETECTED: profile disabled, ERRORS: Antispam: You can't have a profile yet. You need to post a few times first. Click for help.}
Wed Feb 23, 2011 5:03 pm {Spam hammer: CHECKED POST of 'Anonymous'. DETECTED: links, bad words, ERRORS: Your post looks too spamy for a new user, please remove off-site URLs. Click for help., Your post looks too spamy for a new user, please remove bad words or non-english text. (porn) Click for help. CONTENTS: порнофильм данилова.......HUGE LINK LIST REMOVED......}

Example log.

Extreme

private $extreme=false;

This is a class-only setting (adjust it in the code) that turns on some extreme honeypot features. Users with 0 posts are deleted if they:

  • Submit a profile
  • Submit a spammy signature
  • Users with more than $extreme_links_delete link in a first post
private $extreme=true;

Enable this feature (not recommended)

private $extreme_links_delete=9;

Configure the max number of links in a first post. More than this and the user is deleted automatically. Users are returned to the post with an error so they can copy and paste the post for later if it was legit.

Zombie registration purge

We get 100s of script registrations every day. Captchas, challenge questions, and other stuff only stops the stupidest scripts, and annoys users. We forbid them from posting links, but that doesn't stop them from registering.

The zombie registration purge deletes all users with 0 posts who are older than the minimum account age.

Weaknesses

There is still a corner case that should be dealt with:

  1. The spammer has one 'innocent' post before the account is deleted, right at the end of the minimum account age before a moderator notices
  2. The spammer posts until minimum posts are reached
  3. After the restrictions are lifted the spam flows

A future option is to made the minimum account age only apply after the first post is made. That gives admins a better chance to notice the suspicious 'innocent' posts and delete the users before the links start flowing. It will require a database query though, so it has not yet been implemented.

Install

SQL

Run this SQL from phpmyadmin, etc:

INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('links_after_num_posts', '0', '0');
INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('links_after_num_days', '0', '0');
INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('links_allow_always', '', '0');
INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('links_link_strings', 'http://,www.,.com,.net,.org,.uk,.ly,.me,.ru,.biz,.info,dot com,dot net,dot org,dotcom,dotnet,dotorg,_com,_org,_co_uk,_ru,dot ru', '0');
INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('links_word_strings', 'home mortage,forex,free games', '0');
INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('links_unicode_filter', '', '0');
INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('links_nonunicode_percent', '', '0');
INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('links_help_url', '', '0');
INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('links_disable_sleepers', '0', '0');
INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('links_first_post_length', '0', '0');
INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('links_log_activity', '0', '0');
INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('links_delete_zombies', '0', '0');
INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('links_delete_zombies_days', '0', '0');

posting.php

Find in /posting.php:

if ($submit || $preview || $refresh)
{
    $post_data['topic_cur_post_id']    = request_var('topic_cur_post_id', 0);
    $post_data['post_subject']        = utf8_normalize_nfc(request_var('subject', '', true));
    $message_parser->message        = utf8_normalize_nfc(request_var('message', '', true));

Add under:

    //---------------------------------------------------------------//
    //check for URLs and bad words in new user post
    require($phpbb_root_path . 'includes/functions_link_filter.' . $phpEx);
    $f= new link_filter; //new link filter
    if($f->link_filter_test_post($message_parser->message, $post_data['post_subject']))//run the check
    {
    $error = array_merge($error, $f->error);//add the errors to the error array, if any
    }
    unset($f);
    //---------------------------------------------------------------//

ucp_profile.php

Find In /includes/ucp/ucp_profile.php:

            case 'profile_info':

Add under:

                //---------------------------------------------------------------//
                //display warning that new users can't have a profile
                require($phpbb_root_path . 'includes/functions_link_filter.' . $phpEx);
                $f= new link_filter; //new link filter
                if($f->link_filter_test_profile($submit))//run the check
                {
                $error = array_merge($error, $f->error);//add the errors to the error array, if any
                }
                //---------------------------------------------------------------//

Find:

                    if (!check_form_key('ucp_profile_info'))
                    {
                        $error[] = 'FORM_INVALID';
                    }

Add under:

                //-------------------------------------------------------//
                // don;t allow new users to update profile
                    if(sizeof($f->error))//run the check
                    {
                    $error = array_merge($error, $f->error);//add the errors to the error array, if any
                    }
                //-------------------------------------------------------//

Find

$cp->generate_profile_fields('profile', $user->get_iso_lang_id());

Add under

                //-------------------------------------------------------//   
                //unset f clear down here incase we want to do something more interesting with it later           
                unset($f);
                //-------------------------------------------------------//

Find

                        if (!check_form_key('ucp_sig'))
                        {
                            $error[] = 'FORM_INVALID';
                        }

Add under

//---------------------------------------------------------------//
//check for URLs and bad words in new user signature
require($phpbb_root_path . 'includes/functions_link_filter.' . $phpEx);
$f= new link_filter; //new link filter
if($f->link_filter_test_signature($signature))//run the check
{
$error = array_merge($error, $f->error);//add the errors to the error array, if any
}
unset($f);
//---------------------------------------------------------------//

ucp_pm_compose.php

Find in /includes/ucp/ucp_pm_compose.php:

    if ($submit || $preview || $refresh)
    {
        if (($submit || $preview) && !check_form_key('ucp_pm_compose'))
        {
            $error[] = $user->lang['FORM_INVALID'];
        }
        $subject = utf8_normalize_nfc(request_var('subject', '', true));
        $message_parser->message = utf8_normalize_nfc(request_var('message', '', true));

Add under

    //---------------------------------------------------------------//
    //check for URLs and bad words in new user post
    require($phpbb_root_path . 'includes/functions_link_filter.' . $phpEx);
    $f= new link_filter; //new link filter
    if($f->link_filter_test_post($message_parser->message, $subject))//run the check
    {
    $error = array_merge($error, $f->error);//add the errors to the error array, if any
    }
    unset($f);
    //---------------------------------------------------------------//

board.php

Find in /language/en/acp/board.php:

    'SMILIES_PER_PAGE'                => 'Smilies per page',
    'TOPICS_PER_PAGE'                => 'Topics per page',

Add after:

    //--------------------------------------------------------
    'LINKS_FILTER_OPTIONS' => 'spam hammer',
    'LINKS_AFTER_NUM_POSTS'            => 'Min post count before posting external links',
    'LINKS_AFTER_NUM_POSTS_EXPLAIN'    => 'Users will need this number of posts before they are able to use the [URL] BBCode tag or post external page urls and domain references. Applies to posts, signatures, PMs, and profiles.',
    'LINKS_AFTER_NUM_DAYS'            => 'Min days from registration before posting external links',
    'LINKS_AFTER_NUM_DAYS_EXPLAIN'    => 'Users will need to have registered this many days before they are able to use the [URL] BBCode tag or post external page urls and domain references. Applies to posts, signatures, PMs, and profiles.',   
    'LINKS_LINK_STRINGS' => 'Link search strings',
    'LINKS_LINK_STRINGS_EXPLAIN' => 'Anything in this line is considered a link and cannot be posted by a new user.',
    'LINKS_WORD_STRINGS' =>'Bad word search strings',      
    'LINKS_WORD_STRINGS_EXPLAIN' =>'Anything in this line cannot be used in a new user post.',  
    'LINKS_ALLOW_ALWAYS' =>'Link whitelist',      
    'LINKS_ALLOW_ALWAYS_EXPLAIN' =>'In addition to links at the same site as the forum, new users can also posts links to these sites.',  
    'LINKS_UNICODE_FILTER' =>'Unicode REGEX filter',  
    'LINKS_UNICODE_FILTER_EXPLAIN' =>'A REGEX filter that detects unicode characters not normally used in the language of the forum. Leave blank to disable.',  
    'LINKS_NONUNICODE_PERCENT' =>'Non-unicode threshold',  
    'LINKS_NONUNICODE_PERCENT_EXPLAIN' =>'What percent of a post must be non-unicode characters. Enter as 0.95 for 95%, leave blank to disable.',      
    'LINKS_HELP_URL' =>'Filter help link',  
    'LINKS_HELP_URL_EXPLAIN' =>'A link to a post that explains the filter criteria. Leave blank to disable.',      
    'LINKS_DISABLE_SLEEPERS'        =>'Disable sleeper agents',
    'LINKS_DISABLE_SLEEPERS_EXPLAIN'=>'Disable posting, signature, and profiles for new users with 0 posts after minimum days (above). Prevents old accounts from coming back as spammers.',  
    'LINKS_FIRST_POST_LENGTH'=> 'Min first post and guest post characters',
    'LINKS_FIRST_POST_LENGTH_EXPLAIN'=>'First post and guest post must be at least this many characters. 0 to disable.',
    'LINKS_LOG_ACTIVITY'=>'Log filter activity',
    'LINKS_LOG_ACTIVITY_EXPLAIN'=>'Logs all filter activity to system log. Not recommended.',
    'LINKS_DELETE_ZOMBIES'=>'Delete zombie registrations',
    'LINKS_DELETE_ZOMBIES_EXPLAIN'=>'Purges users with 0 posts after the number of days set below.',
    'LINKS_DELETE_ZOMBIES_DAYS'=>'Days before zombie purge',
    'LINKS_DELETE_ZOMBIES_DAYS_EXPLAIN'=>'How many days before a zombie account with 0 posts is deleted.',
    //-----------------------------------------------------------

acp_board.php

Find in /includes/acp/acp_board.php:

'max_post_img_width'=> array('lang' => 'MAX_POST_IMG_WIDTH','validate' => 'int:0','type' => 'text:5:4', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']),
'max_post_img_height'=> array('lang' => 'MAX_POST_IMG_HEIGHT','validate' => 'int:0','type' => 'text:5:4', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']),

Add after:

//-------------------------------------------------------------//
                        'legend4'				=> 'Spam Hammer',
                        'links_after_num_posts'   => array('lang' => 'LINKS_AFTER_NUM_POSTS', 'validate' => 'int:0',   'type' => 'text:4:4', 'explain' => true),
                        'links_after_num_days'    => array('lang' => 'LINKS_AFTER_NUM_DAYS', 'validate' => 'int:0',   'type' => 'text:4:4', 'explain' => true),
                        'links_disable_sleepers'  => array('lang' => 'LINKS_DISABLE_SLEEPERS',    'validate' => 'bool',    'type' => 'radio:yes_no', 'explain' => true),   
                        'links_first_post_length'  => array('lang' => 'LINKS_FIRST_POST_LENGTH', 'validate' => 'int:0',   'type' => 'text:4:4', 'explain' => true),                        
                        'links_link_strings'    => array('lang' => 'LINKS_LINK_STRINGS','validate' => 'string',    'type' => 'text:40:255', 'explain' => true),
                        'links_word_strings'    => array('lang' => 'LINKS_WORD_STRINGS','validate' => 'string',    'type' => 'text:40:255', 'explain' => true),
                        'links_allow_always'    => array('lang' => 'LINKS_ALLOW_ALWAYS','validate' => 'string',    'type' => 'text:40:255', 'explain' => true),
                        'links_unicode_filter'    => array('lang' => 'LINKS_UNICODE_FILTER','validate' => 'string',    'type' => 'text:40:255', 'explain' => true),
                        'links_nonunicode_percent'    => array('lang' => 'LINKS_NONUNICODE_PERCENT','validate' => 'string',    'type' => 'text:40:255', 'explain' => true),
                        'links_help_url'    => array('lang' => 'LINKS_HELP_URL','validate' => 'string',    'type' => 'text:40:255', 'explain' => true),                   
                        'links_log_activity'  => array('lang' => 'LINKS_LOG_ACTIVITY',    'validate' => 'bool',    'type' => 'radio:yes_no', 'explain' => true),                               
                        'links_delete_zombies'  => array('lang' => 'LINKS_DELETE_ZOMBIES',    'validate' => 'bool',    'type' => 'radio:yes_no', 'explain' => true),       
                        'links_delete_zombies_days'  => array('lang' => 'LINKS_DELETE_ZOMBIES_DAYS', 'validate' => 'int:0',   'type' => 'text:4:4', 'explain' => true),
 
//-------------------------------------------------------------//

functions_link_filter.php

Put the class in includes/functions_link_filter.php.

Zombie registration purge install

The zombie registration purge deletes all users with 0 posts who are older than the link posting age window.

  • Most spam is at least partially automated. Why should you spend more time cleaning up than they do posting it?
  • Part of the link_filter class, but more hacky and less well developed
  • Be sure to backup in case something goes wrong, you'll be letting the forum automagically delete users
  • Piggybacks onto the (usually) every-two-hours tidy_cache cron job.
  • Leaves a log message with the deleted users

cron.php

Find in /cron.php:

        if (time() - $config['cache_gc'] <= $config['cache_last_gc'] || !method_exists($cache, 'tidy'))
        {
            break;
        }

REPLACE with:

        if (time() - $config['cache_gc'] <= $config['cache_last_gc'])
        {
            break;
        }
        //---------------------------------------------------------------//
        //purge zombie registrations
        include_once($phpbb_root_path . 'includes/functions_user.' . $phpEx);
        require($phpbb_root_path . 'includes/functions_link_filter.' . $phpEx);
        $f= new link_filter; //new link filter
        $f->link_filter_purge_zombies();//run the check
        unset($f);
        //---------------------------------------------------------------//
        if(!method_exists($cache, 'tidy'))
        {
            break;
        }

To do

  1. Sliding window based on first post time
  2. Better "cron" integration for zombie purge
  3. Apply only to the new user group?