Take the 2-minute tour ×
Webmasters Stack Exchange is a question and answer site for pro webmasters. It's 100% free, no registration required.

Possible Duplicate:
How can I prevent spam on sites which I control?

I'm looking for something like spam-assassin or similar, except it only focuses on the message rather than inspecting an entire email header.

It doesn't even need to be really fancy, just do the classification of messages. In theory we could provide meta-data such as IP.

I'm doing this because I want an feedback forum without authentication or recaptcha or having to put every email in the "pending" bin before it's published.

share|improve this question

marked as duplicate by Christofian Aug 29 '12 at 1:12

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

add comment

2 Answers

up vote 2 down vote accepted

Have you considered Akismet? It's excellent at catching spam.

share|improve this answer
    
Yeah and I've also looked at sblam-- but I'd like to do something that doesn't involve third-party api latency. –  Incognito Dec 3 '11 at 18:33
1  
Nothing will be as good as a hosted service like Akismet which analyzes thousands of posts per second across thousands of sites on the internet. The AI/Machine Learning aspects are only possible when used at a large scale. I think you should try to build your application in a way that queries Akismet asynchronously if you're worried about latency - design it in a way that the user doesn't have to wait for you to query Akismet. –  Max Dec 4 '11 at 20:07
add comment

You can create your own spam filter classes and use it.

I use following class to detect spam on comments:

 class CommonFunctions{

        private $spam_array = array('.com','.net','.org','.biz','.coop','.info','.museum','.name','.pro'
        ,'.edu','.gov','.int','.mil','.ac','.ad','.ae','.af','.ag','.ai','.al',
        '.am','.an','.ao','.aq','.ar','.as','.at','.au','.aw','.az','.ba','.bb',
        '.bd','.be','.bf','.bg','.bh','.bi','.bj','.bm','.bn','.bo','.br','.bs',
        '.bt','.bv','.bw','.by','.bz','.ca','.cc','.cd','.cf','.cg','.ch','.ci',
        '.ck','.cl','.cm','.cn','.co','.cr','.cu','.cv','.cx','.cy','.cz','.de',
        '.dj','.dk','.dm','.do','.dz','.ec','.ee','.eg','.eh','.er','.es','.et',
        '.fi','.fj','.fk','.fm','.fo','.fr','.ga','.gd','.ge','.gf','.gg','.gh',
        '.gi','.gl','.gm','.gn','.gp','.gq','.gr','.gs','.gt','.gu','.gv','.gy',
        '.hk','.hm','.hn','.hr','.ht','.hu','.id','.ie','.il','.im','.in','.io',
        '.iq','.ir','.is','.it','.je','.jm','.jo','.jp','.ke','.kg','.kh','.ki',
        '.km','.kn','.kp','.kr','.kw','.ky','.kz','.la','.lb','.lc','.li','.lk',
        '.lr','.ls','.lt','.lu','.lv','.ly','.ma','.mc','.md','.mg','.mh','.mk',
        '.ml','.mm','.mn','.mo','.mp','.mq','.mr','.ms','.mt','.mu','.mv','.mw',
        '.mx','.my','.mz','.na','.nc','.ne','.nf','.ng','.ni','.nl','.no','.np',
        '.nr','.nu','.nz','.om','.pa','.pe','.pf','.pg','.ph','.pk','.pl','.pm',
        '.pn','.pr','.ps','.pt','.pw','.py','.qa','.re','.ro','.rw','.ru','.sa',
        '.sb','.sc','.sd','.se','.sg','.sh','.si','.sj','.sk','.sl','.sm','.sn',
        '.so','.sr','.st','.sv','.sy','.sz','.tc','.td','.tf','.tg','.th','.tj',
        '.tk','.tm','.tn','.to','.tp','.tr','.tt','.tv','.tw','.tz','.ua','.ug',
        '.uk','.um','.us','.uy','.uz','.va','.vc','.ve','.vg','.vi','.vn','.vu',
        '.ws','.wf','.ye','.yt','.yu','.za','.zm','.zw');







        /*
        *find whether a string contains html
        *@param string
        *@return boolean
        */
        public function containHtml($data){

            if(strlen($data) != strlen(strip_tags($data))){
                return true;
            } 

            return false;

        }
        //function end

        public function isOK($data){
            if(strlen(trim($data))>0){
                if(!$this->containHtml($data)){
                    if(!$this->containSpam($data)){
                        return true;    
                    }
                }
            }
            return false;
        }
        /*
        *find whether a string contains spam
        *@param string
        *@return boolean
        */
        public function containSpam($data){
            $data=strtolower($data);
            foreach($this->spam_array as $spam_word){
                //echo "<br>Data is $data Word is $spam_word ".stripos($data,$spam_word)."<br/>";

                if($this->cusFnmatch("*$spam_word*",$data)){
                    return true;
                }           

            }

            return false;

        }
        //function end


        function cusFnmatch($needl,$check_string){

            if (!function_exists('fnmatch')) {
                define('FNM_PATHNAME', 1);
                define('FNM_NOESCAPE', 2);
                define('FNM_PERIOD', 4);
                define('FNM_CASEFOLD', 16);

                function fnmatch($pattern, $string, $flags = 0) {
                    return pcre_fnmatch($pattern, $string, $flags);
                }
            }

           if(!function_exists('pcre_fnmatch')){

                function pcre_fnmatch($pattern, $string, $flags = 0) {
                    $modifiers = null;
                    $transforms = array(
                        '\*'    => '.*',
                        '\?'    => '.',
                        '\[\!'    => '[^',
                        '\['    => '[',
                        '\]'    => ']',
                        '\.'    => '\.',
                        '\\'    => '\\\\'
                    );

                    // Forward slash in string must be in pattern:
                    if ($flags & FNM_PATHNAME) {
                        $transforms['\*'] = '[^/]*';
                    }

                    // Back slash should not be escaped:
                    if ($flags & FNM_NOESCAPE) {
                        unset($transforms['\\']);
                    }

                    // Perform case insensitive match:
                    if ($flags & FNM_CASEFOLD) {
                        $modifiers .= 'i';
                    }

                    // Period at start must be the same as pattern:
                    if ($flags & FNM_PERIOD) {
                        if (strpos($string, '.') === 0 && strpos($pattern, '.') !== 0) return false;
                    }

                    $pattern = '#^'
                        . strtr(preg_quote($pattern, '#'), $transforms)
                        . '$#'
                        . $modifiers;

                    return (boolean)preg_match($pattern, $string);
                } 
            }
            return fnmatch($needl,$check_string);
        }

    }

and i'll check for spam like this,

include_once "class.commonfunctions.php";

$cmn=new CommonFunctions();
if(!$cmn->isOK($comment))
{
    return false;
}
else{

 //proceed with insert

}
share|improve this answer
    
I don't know why i've given downvote, the questioner doesn't like to use third party software so i suggested one class which will block urls and spam words if set. How this qualify for a down vote? –  Sekar Jan 6 '12 at 7:36
add comment

Not the answer you're looking for? Browse other questions tagged or ask your own question.