51 (edited by eric235u 2007-05-19 16:36)

Re: Vulnerable to spambots

[my two cents]

when i join a website or forum i despise overly time consuming activation processes.  i'm not a trick pony and don't jump through hoops.

it seems that the best way of slowing down spam is to keep the methods varied and modular.  if there's four or five punbb antispam modules that all work differently we would be in a better strategic position than if one module were included in the official release.  this argument i think is self evident.

[/my two cents]

Re: Vulnerable to spambots

eric235u wrote:

[my two cents]

when i join a website or forum i despise overly time consuming activation processes.  i'm not a trick pony and don't jump through hoops.

it seems that the best way of slowing down spam is to keep the methods varied and modular.  if there's four or five punbb antispam modules that all work differently we would be in a better strategic position than if one module were included in the official release.  this argument i think is self evident.

[/my two cents]

Agreed (although certain mods are very effective, I've seen Akismet work very well on the PunBB blog)

53

Re: Vulnerable to spambots

Smartys wrote:

Spammers already pay people to manually register accounts for them wink

Humm. 10 thousands forums in the world? When each admin can change the question as often as he want?

Plus, this makes for a great deal more work for the administrator

I don't think so. It's not a difficult job. More easy as to find a good extension when computer or internet is not your job and you want to find a good and easy forum for your site...

Re: Vulnerable to spambots

gil wrote:

...More easy as to find a good extension when computer or internet is not your job and you want to find a good and easy forum for your site...

you just negated you argument in one sentence. wink

~James
FluxBB - Less is more

55

Re: Vulnerable to spambots

gil wrote:
yemgi wrote:

If you allow guest posting or do not enable rules and and email registration then you will not be able to avoid SPAM. Whichever forum software you use this is a basic way to limit SPAM.
It is more a management/policy issue than a software one.

If you're true, so these options (enabling guest posting or using no rules) can be deleted from punbb, as there are not usable... No ?

I'm sorry, but nowadays I think it's not only a management/policy issue, it's a software one... Not really a bug, but a missing capacity.

Why should they be deleted ? Some people wants and use them. What I said is if you set your forums this way, there is no way to stop SPAM whichever forum software you use.

56 (edited by sirena 2007-05-20 00:52)

Re: Vulnerable to spambots

Another anti-bot signup idea:

When email registration is enabled, the new registrant is sent the usual confirmation email by punBB, but the email from punBB also encloses a **randomly generated** 5 or 6 digit numeric code or even a dictionary word. Accompanying this code is a link to a simple 'confirm details' page on punBB, where they are asked to enter the code they received in the email before their can be registration is accepted and an account created on the forum.

At initial sign-up, register.php would create and then store this code against the email address the person signed up with. When they come back to confirm these details, the code they are required to manually enter would be compared with the code created for them at initial signup by punBB.

This 'two-factor' email signup is an a easier way to implement a CAPTCHA, without any of the problems associated with images etc. But it should still be pretty robust, at least against scripted bots, since the secondary password would be random.

This approach could also largely piggyback on existing punBB forms and mechanisms.

Edit: I just saw the flaw in this - you are essentially just feeding the bot the password to use by sending it out in the email. It can then just parse the email, grab the password and feed it back into the secondary form (depending on the capability of the scripting tool the forum spammers use). No progress. sad

Sorry for bothering everyone.

57

Re: Vulnerable to spambots

yemgi wrote:
gil wrote:
yemgi wrote:

If you allow guest posting or do not enable rules and and email registration then you will not be able to avoid SPAM. Whichever forum software you use this is a basic way to limit SPAM.
It is more a management/policy issue than a software one.

If you're true, so these options (enabling guest posting or using no rules) can be deleted from punbb, as there are not usable... No ?

I'm sorry, but nowadays I think it's not only a management/policy issue, it's a software one... Not really a bug, but a missing capacity.

Why should they be deleted ? Some people wants and use them.

Flooded by porn picture spam? It's not what one can say "usable"... Not my opinion, at least.

What I said is if you set your forums this way, there is no way to stop SPAM whichever forum software you use.

I don't think so. I think that the "anti-captcha" should be personalised by the admin, and should not be a hard-coded question for example. Like a question and answer defined by the admin for example, but one can find another solution, I don't know.

Re: Vulnerable to spambots

Perhaps the answer here is a more robust security class.

Possibly use some javascript for client authentication with some redirecting.

A few classes come to mind offhand.

using a robust security class in combination with session protection on all input FORMs might be along the lines of what is needed here.

<?php

############################################################################# 
# 
#          PHP CLASS:       c_security.php     (stand alone security class)
#
# Cafe CounterIntelligence SoapCMS Core Security Class 
# Copyright 2004 Mike Parniak 
# www.voodoochat.com 
# 
# This program is free software; you can redistribute it and/or modify 
# it under the terms of the GNU General Public License as published by 
# the Free Software Foundation; either version 2 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 General Public License for more details. 
# 
# You should have received a copy of the GNU General Public License 
# along with this program; if not, write to the Free Software 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
# 
# Purpose: Base flood, XSS and SQL Injection protection 
# 
# Requires: Nothing. 
#
#    require_once("c_security.php");
#    $mysecurity = new soapSecurity();
#
#
# 
# Usage: create an instance of the soapSecurity object at the beginning of 
# any publically accessible scripts. GET, POST, and COOKIE variables 
# that are strictly numeric should begin with "n_". 
# 
############################################################################# 

class soapSecurity { 

var $ip; 
var $csUn = "Soap"; 
var $vkeyname; 
var $vhash; 
var $vsession; 
var $vsesscook; 

// Initialization function 

function soapSecurity($dosanitize = 1) { 

ini_set("session.use_only_cookies","1"); 
ini_set("session.use_trans_sid","0"); 

$ip = $_SERVER["REMOTE_ADDR"]; 
$vkeyname = md5($_SERVER["REMOTE_ADDR"] . $_SERVER["HTTP_HOST"] .
$_SERVER["DOCUMENT_ROOT"] . $csUn); 
$vhash = md5($_SERVER["REMOTE_ADDR"] . $_SERVER["HTTP_USER_AGENT"] . 
$_SERVER["HTTP_HOST"] . $_SERVER["DOCUMENT_ROOT"] . 
$_SERVER["SERVER_SOFTWARE"] . $_SERVER["PATH"] . $csUn); 
$vsession = md5($_SERVER["REMOTE_ADDR"] . $_SERVER["HTTP_HOST"] . $csUn); 
$vsesscook = md5($_SERVER["REMOTE_ADDR"] . $_SERVER["DOCUMENT_ROOT"] .
$_SERVER["HTTP_HOST"]); 

srand(time()); 
session_name($vhash); 
session_id($vsession); // Begin data-specific session 
session_start(); 

if ((!isset($_SESSION["soapsec-rtg"])) || ($_SESSION["soapsec-rtg"]<1))
{ 
$_SESSION["soapsec-rtg"] = rand(3,5); 
$_SESSION["soapsec-romps"] = 0; 
$_SESSION["soapsec-ourl"] = $_SERVER["REQUEST_URI"]; 
$_SESSION["soapsec-rcode"] = md5($_SERVER["REMOTE_ADDR"] .
$_SERVER["HTTP_USER_AGENT"] . 
$_SERVER["HTTP_HOST"] . $_SERVER["DOCUMENT_ROOT"] . 
$_SERVER["SERVER_SOFTWARE"] . $_SERVER["PATH"] .
$_SESSION["soapsec-romps"] . time()); 
} 

if (($_SESSION["soapsec-rtg"]>0) &&
($_SESSION["soapsec-romps"]<$_SESSION["soapsec-rtg"])) { 
if (($_GET[$vkeyname] == $_SESSION["soapsec-rcode"]) &&
($_GET[$vkeyname] != "")) { 
$_SESSION["soapsec-romps"]++; 
} else $_SESSION["soapsec-errors"]+=2; 
if ($_SESSION["soapsec-romps"] < $_SESSION["soapsec-rtg"]) { 
$_SESSION["soapsec-rcode"] = md5($_SERVER["REMOTE_ADDR"] .
$_SERVER["HTTP_USER_AGENT"] . 
$_SERVER["HTTP_HOST"] . $_SERVER["DOCUMENT_ROOT"] . 
$_SERVER["SERVER_SOFTWARE"] . $_SERVER["PATH"] .
$_SESSION["soapsec-romps"] . time()); 
$numromps = $_SESSION["soapsec-romps"]; 
session_write_close(); 
$thisurl = $_SERVER["REQUEST_URI"]; 
$thisurl = eregi_replace("\?.*","",$thisurl); 
$thisurl = "http://" . $_SERVER["HTTP_HOST"] . $thisurl . "?"; 
$outkey = $vkeyname . "=" . $_SESSION["soapsec-rcode"]; 

// First romp is less CPU intensive, in cases of weak automated requesters.

if ($numromps==1) {
header("Location: " . $thisurl . $outkey);
exit(); 
} 

// Subsequent romps are tricky, using hard-to-parse javascript. 

$rnu = rand(8,15); 
$ran = array(); 
$jsout = "<SCRIPT LANGUAGE=\"JavaScript\">\n"; 
for ($i = 0;$i < $rnu;$i++) { 
$ran[$i] = rand(-65,65); 
$jsout .= "var " . chr(97+$i) . " = " . $ran[$i] . "; "; 
} 

$outlen = strlen($outkey); 

$jsout .= "var z = new Array(); "; 
$myvars = array(); 

$onvar = 0; 
for ($i = 0;$i < $outlen;$i++) { 
if ($onvar >= $rnu) $onvar = 0; 
$thediff = $i - $ran[$onvar]; 
$myvars[$i] = "z[" . chr(97+$onvar); 
if ($thediff>0) $myvars[$i].= "+"; 
if ($thediff<>0) $myvars[$i] .= $thediff; 
$myvars[$i] .= "] = \"" . $outkey[$i] . "\"; "; 
$onvar++; 
} 
shuffle($myvars); 
$jsout .= implode('',$myvars); 
$jsout .= "var x = z.join(\"\"); "; 
$jsout .= "location.replace(\"" . $thisurl . "\" +
x);</SCRIPT><noscript>You must enable Javascript in order to view this
webpage.</noscript>"; 
echo $jsout; 
} else { 
$thisurl = "http://" . $_SERVER["HTTP_HOST"] .
$_SESSION["soapsec-ourl"]; 
echo "<SCRIPT
LANGUAGE=\"JavaScript\">location.replace(\"$thisurl\");</SCRIPT><noscrip
t>You must enable Javascript in order to view this webpage.</noscript>"; 
} 
exit(); 
} 

if ($dosanitize) { 

$getvariables = array_keys($_GET); 
$count = 0; 
while($count < count($getvariables)) { 
$_GET[$getvariables[$count]] = $this ->
sanitize($_GET[$getvariables[$count]],(strpos($getvariables[$count],"n_")===0)
); 
$count++; 
} 
$getvariables = array_keys($_POST); 
$count = 0; 
while($count < count($getvariables)) { 
$_POST[$getvariables[$count]] = $this ->
sanitize($_POST[$getvariables[$count]],(strpos($getvariables[$count],"n_")===0
)); 
$count++; 
} 
$getvariables = array_keys($_COOKIE); 
$count = 0; 
while($count < count($getvariables)) { 
$_COOKIE[$getvariables[$count]] = $this ->
sanitize($_COOKIE[$getvariables[$count]],(strpos($getvariables[$count],"n_")===0));
$count++; 
} 
} 

// If server has automatic global creation, destroy automatically created
variables. 
// but... make sure that the variable's value matches the request variable's value before destroying it.

$getvariables = array_keys($_REQUEST); 
$count = 0; 
while($count < count($getvariables)) { 
if ((isset($getvariables[$count])) && ($GLOBALS[$getvariables[$count]] ==
$_REQUEST[$getvariables[$count]])) { 
unset($GLOBALS[$getvariables[$count]]); 
} 
$count++; 
} 

// Remove our session and initiate or restore the user session. 

if (isset($_COOKIE["$vsesscook"])) { 
session_write_close(); 
session_name($vsesscook); 
session_id($_COOKIE["$vsesscook"]); 
session_start(); 
if (!isset($_SESSION["soap-flag"])) { 
setcookie($vsesscook,"",0,"/"); 
session_unset(); 
session_destroy(); 
unset($_COOKIE["$vsesscook"]); 
Header("Location: http://" . $_SERVER["HTTP_HOST"] .
$_SERVER["REQUEST_URI"]); 
exit(); 
} 
} else { 
if ((time()-120)<$_SESSION["soapsec-lastsess"]) { 
if ($_SESSION["soapsec-fastsess"]>2) { 
$_SESSION["soapsec-lastsess"] = time(); 
exit(); 
} 
} else $_SESSION["soapsec-fastsess"] = 0; 

$_SESSION["soapsec-lastsess"] = time(); 
$_SESSION["soapsec-fastsess"]++; 
session_write_close; 
session_name($vsesscook); 
session_id(md5(uniqid(time()))); 
session_start(); 
setcookie($vsesscook,session_id(),0,"/"); 
$_SESSION["soap-flag"] = 1; 
} 

if ($this -> floodcheck("fastaccess",3,6)) exit(); 

return; 
} 

// Removes potentially hazardous material from a string (anti-XSS, anti-Injection)
// Reliable anti-injection requires cgi variables use the n_ naming convention for any 
// variable that is strictly numeric and possibly used in a query. 

function sanitize($tosanitize,$numonly=FALSE) { 
if ($numonly) { 
$tosanitize = eregi_replace("[^0-9\.\-]","",$tosanitize); 
} else { 
$tosanitize = htmlspecialchars($tosanitize); 
$tosanitize =
eregi_replace("javascript:","javascript:",$tosanitize); 
if (!get_magic_quotes_gpc()) $tosanitize = addslashes($tosanitize); 
} 
return $tosanitize; 
} 

// Generic flood checking routine 

function floodcheck($identifier,$interval,$threshold=1) { 
$myresult = 0; 
if (isset($_SESSION["soapsec-" . $identifier])) { 
if ($_SESSION["soapsec-" . $identifier] > (time()-$interval)) { 
if ($threshold<2) { 
$myresult = 1; 
} else { 
if (!isset($_SESSION["soapsec-" . $identifier . "-counter"])) { 
$_SESSION["soapsec-" . $identifier . "-counter"] = 1; 
} else { 
$_SESSION["soapsec-" . $identifier . "-counter"]++; 
if ($_SESSION["soapsec-" . $identifier . "-counter"] >=
$threshold) { 
$myresult = 1; 
} 
} 
} 
} else $_SESSION["soapsec-" . $identifier . "-counter"] = 1; 
} 
$_SESSION["soapsec-" . $identifier] = time(); 
return $myresult; 
} 
}
?>
<?php

#############################################################################
#                                                                           #
# Cafe CounterIntelligence PHP Website Security Script 1.8                  #
# Copyright 2002, 2003 Mike Parniak                                         #
# www.voodoochat.com                                           #
#                                                                           #
# This program is free software; you can redistribute it and/or modify      #
# it under the terms of the GNU General Public License as published by      #
# the Free Software Foundation; either version 2 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 General Public License for more details.                              #
#                                                                           #
# You should have received a copy of the GNU General Public License         #
# along with this program; if not, write to the Free Software               #
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA   #
#                                                                           #
# Usage: require_once("ccisecurity.php"); at the start of website scripts.  #
#                                                                           #
#############################################################################

##################
#
# Configuration Section - Set these variables first (Or use default if you want)
#
##################

$usehtaccessbans = 1;            # 1 = modify .htaccess to ban IPs, 0 = don't ban IPs.
$filterGETvars = 1;                # 1 = sterilize HTML tags in GET variables, 0 = don't
$filterCOOKIEvars = 1;            # 1 = sterilize HTML tags in COOKIE variables, 0 = don't
$filterPOSTvars = 0;            # 1 = sterilize HTML tags in POST variables, 0 = don't
$extraPOSTprotection = 0;        # 1 = use the extra POST protection, 0 = don't
$extraGETprotection = 0;        # 1 = use the extra GET protection, 0 = don't (not recommended!)
$checkmultiPOST = 1;            # 1 = only allow maxmultiPOST number of successive POSTs, 0 = don't care
$maxmultiPOST = 5;                # Maximum number of POST operations in a row, if checkmultipost is on.
$zipcompress = 0;                # 1 = Compress pages using GZIP library (lower bandwidth, higher CPU), 0 = don't
$compresslevel = 9;                # Compression level for zipcompressing, from 1 (low) to 9 (maximum)
$cpuloadmonitor = 0;            # 1 = block access if over a certain system load, 0 = don't
$cpumaxload = 10.0;                # Maximum 5 minute system load average before blocking access
$ccisessionpath = "";            # if not blank, sets a directory path to store session files.

##### Encryption/Encoding Variables

$javababble = 0;                # 1 = Use Encoding/Encrypting (Must be on for any), 0 = Don't
$javaencrypt = 0;                # Do actual encrypting of HTML, not just escaping (warning: may slow display)
$preservehead = 0;                # 1 = Only encode/encrypt between BODY tags, 0 = encode/encrypt whole document

##################
#
# Check for in-script overrides
#
##################

if (isset($zipoverride)) {
  if (!isset($_REQUEST["zipoverride"])) {
    $zipcompress = $zipoverride;
    unset($zipoverride);
  }
}

if (isset($babbleoverride)) {
  if (!isset($_REQUEST["babbleoverride"])) {
    $javababble = $babbleoverride;
    unset($babbleoverride);
  }
}

##################
#
# Function: CCIJavaBabble
#
# Usage: Takes some HTML, url-encodes it (jumbles it) then returns the javascript needed to display it properly.
#
##################

function CCIJavaBabble($myoutput) {
  global $mycrypto, $myalpha2, $javaencrypt, $preservehead;
  $s = $myoutput;
  $s = ereg_replace("\n","",$s);

  if ($preservehead) {  
    eregi("(^.+<body[^>]*>)",$s,$chunks);
    $outputstring = $chunks[1];
    eregi_replace($headpart,"",$s);

    eregi("(</body[^>]*>.*)",$s,$chunks);
    $outputend = $chunks[1];
    eregi_replace($footpart,"",$s);
  } else {
    $outputstring = "";
    $outputend = "";
  }
  
  if ($javaencrypt) {
    $s = strtr($s,$myalpha2,$mycrypto);
    $s = rawurlencode($s);
    $outputstring .= "<script>var cc=unescape('$s'); ";
    $outputstring .= "var index = document.cookie.indexOf('" . md5($_SERVER["REMOTE_ADDR"] . $_SERVER["SERVER_ADDR"]) . "='); " .
      "var aa = '$myalpha2'; " .
      "if (index > -1) { " .
      "  index = document.cookie.indexOf('=', index) + 1; " .
      "  var endstr = document.cookie.indexOf(';', index); " .
      "  if (endstr == -1) endstr = document.cookie.length; " .
      "  var bb = unescape(document.cookie.substring(index, endstr)); " .
      "} " .
      "cc = cc.replace(/[$myalpha2]/g,function(str) { return aa.substr(bb.indexOf(str),1) }); document.write(cc);";
  } else {
    $outputstring .= "<script>document.write(unescape('" . rawurlencode($s) . "'));";
  }
  $outputstring .= "</script><noscript>You must enable Javascript in order to view this webpage.</noscript>" . $outputend;
       
  return $outputstring;
}

##################
#
# Function: CCIClearSession
#
# Format: CCIClearSession()
# Returns: Nothing
#
# Usage: Clears all the data out of the session record other than data used for this script
#
##################

function CCIClearSession() {
  $getvariables = array_keys($_SESSION);
  $count = 0;
  while($count < count($getvariables)) {
    if (substr($getvariables[$count],0,7) != "ccisec-") {
      session_unregister($getvariables[$count]); 
      if (ini_get('register_globals')) unset($$getvariables[$count]);
    }
    $count++;
  }
}

##################
#
# Function: CCIBanIP
#
# Format: CCIBanIP(IPAddress)
# Returns: Nothing
#
# Usage: Will open and add a deny line to the .htaccess file in the same directory to deny all
#        accessing by a given IP address.
#
##################

function CCIBanIP($banip) {
  $filelocation = ".htaccess";
  $limitend = "# End of CCI Security Section\n";
  $newline = "deny from $banip\n";
  if (file_exists($filelocation)) {
    $mybans = file($filelocation);
    $lastline = "";
    if (in_array($newline,$mybans)) exit();
    if (in_array($limitend,$mybans)) {      
      $i = count($mybans)-1;
      while ($mybans[$i] != $limitend) {
        $lastline = array_pop($mybans) . $lastline;
        $i--;
      }
      $lastline = array_pop($mybans) . $lastline;
      $lastline = array_pop($mybans) . $lastline;
      $lastline = array_pop($mybans) . $lastline;
      array_push($mybans,$newline,$lastline);
    } else {
      array_push($mybans,"\n\n# CCI Security Script\n","<Limit GET POST>\n","order allow,deny\n",$newline,"allow from all\n","</Limit>\n",$limitend);
    }
  } else {
    $mybans = array("# CCI Security Script\n","<Limit GET POST>\n","order allow,deny\n",$newline,"allow from all\n","</Limit>\n",$limitend);
  }  
  $myfile = fopen($filelocation,"w");
  fwrite($myfile,implode($mybans,""));
  fclose($myfile);
    
}

##################
#
# Function: CCIFloodCheck
#
# Format: CCIFloodCheck("identifier",interval,threshold)
# Returns: 1 if requested without minimum interval, a threshold number of times.  0 if not.
#
# Usage: For functions that require flood control pass a unique identifier, the minimum number of
#        seconds that should be waited between repeats of the function, and a number of times that
#        function can be called too quickly before it sets off the flood trapping.
#
##################

function CCIFloodCheck($identifier,$interval,$threshold=1) {
  $myresult = 0;
  if (isset($_SESSION["ccisec-" . $identifier])) {
    if ($_SESSION["ccisec-" . $identifier] > (time()-$interval)) {
      if ($threshold<2) {
        $myresult = 1;
      } else {
        if (!isset($_SESSION["ccisec-" . $identifier . "-counter"])) {
          $_SESSION["ccisec-" . $identifier . "-counter"] = 1;
        } else {
          $_SESSION["ccisec-" . $identifier . "-counter"]++;
          if ($_SESSION["ccisec-" . $identifier . "-counter"] >= $threshold) {
            $myresult = 1;
          }
        }
      }
    }
    $_SESSION["ccisec-" . $identifier] = time();
  }
  return $myresult; 
}

################################################################################

srand(time());
if (eregi("ccisecurity\.php",$_SERVER["SCRIPT_NAME"])) exit();

if ($ccisessionpath != "") session_save_path($ccisessionpath);
session_name(md5($_SERVER["REMOTE_ADDR"] . $_SERVER["HTTP_HOST"] . "CCI"));

ini_set("session.use_only_cookies","1");
ini_set("session.use_trans_sid","0");

if (($zipcompress) && (eregi("gzip",$_SERVER["HTTP_ACCEPT_ENCODING"]))) {
  ini_set("zlib.output_compression","On");
  ini_set("zlib.output_compression_level",$compresslevel);
  ob_start("ob_gzhandler"); 
}
if ($javababble) {
  if ($javaencrypt) {
    $myalpha = array_merge(range("a","z"),range("A","Z"),range("0","9"));
    $myalpha2 = implode("",$myalpha);
    shuffle($myalpha);
    $mycrypto = implode("",$myalpha);
    setcookie(md5($_SERVER["REMOTE_ADDR"] . $_SERVER["SERVER_ADDR"]),$mycrypto);
    unset($myalpha);
  }
  ob_start("cciJavaBabble");
}

if (substr_count($_SERVER["SERVER_NAME"],".")>1) {
  $cookiedomain = eregi_replace("^[^\.]+\.",".",$_SERVER["SERVER_NAME"]);
} else $cookiedomain = "." . $_SERVER["SERVER_NAME"];

$ip = $_SERVER["REMOTE_ADDR"];
$mykeyname = md5($_SERVER["REMOTE_ADDR"] . $_SERVER["HTTP_HOST"] . $_SERVER["DOCUMENT_ROOT"] . "CCI");
$myposthashname = md5($_SERVER["REMOTE_ADDR"] . $_SERVER["HTTP_HOST"] . $_SERVER["PATH"] . "CCI");

$myhash = md5($_SERVER["REMOTE_ADDR"] . $_SERVER["HTTP_USER_AGENT"] . 
                        $_SERVER["HTTP_HOST"] . $_SERVER["DOCUMENT_ROOT"] . 
                        $_SERVER["SERVER_SOFTWARE"] . $_SERVER["PATH"] . "X");
                                            
$mysession = md5($_SERVER["REMOTE_ADDR"] . $_SERVER["HTTP_HOST"]);                        
session_id($mysession);
session_start();


# Sneaky cookie-storing flooding programs tend to trip this - a cookie not meant to be returned.

if ((isset($_SESSION["ccisec-tripwire"])) && (isset($_COOKIE[$_SESSION["ccisec-tripwire"]]))) {
  CCIBanIP($ip);
  exit();
}
$tripwire = md5(uniqid(time()));
setcookie($tripwire,md5(uniqid(time())),time()-999999,"/",$cookiedomain);
$_SESSION["ccisec-tripwire"]=$tripwire;

# End of the tripwire routine


if (!isset($_SESSION["ccisec-errors"])) $_SESSION["ccisec-errors"] = 0;
if ($_SESSION["ccisec-errors"]>=10) {
  CCIBanIP($ip);
  exit();
}

if ($_SESSION["ccisec-myhash"] != $myhash) {        
  $_SESSION["ccisec-myhash"] = $myhash;
  $_SESSION["ccisec-errors"]++;
  session_write_close();
  Header("Location: http://" . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"]);
  exit();
}

if ((!isset($_COOKIE[$mykeyname])) || ($_COOKIE[$mykeyname] != $myhash)) {
  
  if (!isset($_SESSION["ccisec-nocookie"])) {
    $_SESSION["ccisec-nocookie"] = 1;
  } else {
    $_SESSION["ccisec-nocookie"]++;
  }
  
  if (($usehtaccessbans) && ($_SESSION["ccisec-nocookie"]>10)) CCIBanIP($ip);
    
  setcookie($mykeyname,$myhash,0,"/",$cookiedomain);
       
  if ($_SESSION["ccisec-nocookie"]>2) {
    echo "<b><h1>Access Denied</h1><br><br>You must enable cookies in order to access this website.  Please do so before returning, as continued attempts to access without cookies may result in a banning of this ip ($ip).</b>";
    session_write_close();
    exit();
  } 
  if ($extraGETprotection) {
    $_SESSION["ccisec-hash"] = md5(uniqid(time()));
    setcookie($myposthashname,$_SESSION["ccisec-hash"],0,"/",$cookiedomain);  
  } 
  CCIClearSession();  
  session_write_close();
  Header("Location: http://" . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"]);
  exit();
} else $_SESSION["ccisec-nocookie"] = 0;

if (($usehtaccessbans) && ($_SESSION["ccisec-fastaccesses"]>40)) CCIBanIP($ip);

if ($_SESSION["ccisec-fastaccesses"]>10) {
  if ((time()-60) < $_SESSION["ccisec-lastaccess"]) {
    echo "<b><h1>Access Denied</h1><br><br>There have been too many rapid requests from this IP address ($ip).  You must now wait a full 60 seconds before accessing this site again.</b>";
    $_SESSION["ccisec-fastaccesses"]++;
    $_SESSION["ccisec-lastaccess"]=time();
    exit();
  }
}

if (!isset($_SESSION["ccisec-lastaccess"])) {
  $_SESSION["ccisec-lastaccess"]=time();
} else {
  if ((time()-2) < $_SESSION["ccisec-lastaccess"]) {
    if (!isset($_SESSION["ccisec-fastaccesses"])) $_SESSION["ccisec-fastaccesses"] = 0;
    $_SESSION["ccisec-fastaccesses"]++;
  } else {
    $_SESSION["ccisec-fastaccesses"] = 0;
  }
  $_SESSION["ccisec-lastaccess"]=time();
}

if ($_SERVER["REQUEST_METHOD"] == "POST") {

  if ($checkmultiPOST) {
    if (($_SESSION["ccisec-lastoperation"] == "POST") && ($_SESSION["ccisec-opcount"] >= $maxmultiPOST)) {
      echo "<b><h1>Access Denied</h1><br><br>You may not make multiple POST operations in sequence - please return to the website and try again.</b>";
      $_SESSION["ccisec-errors"]++;
      exit(); 
    }
  }     

  if ($extraPOSTprotection) {
    if ((!isset($_COOKIE[$myposthashname])) || ($_COOKIE[$myposthashname] != $_SESSION["ccisec-hash"])) {
      echo "<b><h1>Access Denied</h1><br><br>Your browser did not send the correct security data needed to complete a POST operation.  Make sure that you have cookies enabled and then try again, or contact the administration if you feel you are receiving this message in error.</b>";
      $_SESSION["ccisec-errors"]++;
      exit();
    }
  }
} else if (($extraGETprotection) && ($_SERVER["REQUEST_METHOD"] == "GET")) {
  if ((!isset($_COOKIE[$myposthashname])) || ($_COOKIE[$myposthashname] != $_SESSION["ccisec-hash"])) {
    echo "<b><h1>Access Denied</h1><br><br>Your browser did not send the correct security data needed to complete a GET operation.  Make sure that you have cookies enabled and then try again, or contact the administration if you feel you are receiving this message in error.</b>";
    $_SESSION["ccisec-errors"]++;
    exit();
  }
} else if ($_SERVER["REQUEST_METHOD"] != "GET") {
  exit();
}

if (($extraPOSTprotection) || ($extraGETprotection)) {
  srand(time());
  $_SESSION["ccisec-hash"] = md5(uniqid(time()));
  setcookie($myposthashname,$_SESSION["ccisec-hash"],0,"/",$cookiedomain);
}

if ($_SESSION["ccisec-lastoperation"] == $_SERVER["REQUEST_METHOD"]) {
  if (!isset($_SESSION["ccisec-opcount"])) {
    $_SESSION["ccisec-opcount"] = 1;
  } else {
    $_SESSION["ccisec-opcount"]++;
  }
} else $_SESSION["ccisec-lastoperation"] = $_SERVER["REQUEST_METHOD"];

# Make special characters safe in any GET based cgi variables.

if ($filterGETvars) {
  $getvariables = array_keys($_GET);
  $count = 0;
  while($count < count($getvariables)) {
    $_GET[$getvariables[$count]] = htmlspecialchars($_GET[$getvariables[$count]]);
    if (ini_get('register_globals')) $$getvariables[$count] = $_GET[$getvariables[$count]];
    $count++;
  }
}

if ($filterPOSTvars) {
  $getvariables = array_keys($_POST);
  $count = 0;
  while($count < count($getvariables)) {
    $_POST[$getvariables[$count]] = htmlspecialchars($_POST[$getvariables[$count]]);
    if (ini_get('register_globals')) $$getvariables[$count] = $_POST[$getvariables[$count]];
    $count++;
  }
}

if ($filterCOOKIEvars) {
  $getvariables = array_keys($_COOKIE);
  $count = 0;
  while($count < count($getvariables)) {
    $_COOKIE[$getvariables[$count]] = htmlspecialchars($_COOKIE[$getvariables[$count]]);
    if (ini_get('register_globals')) $$getvariables[$count] = $_COOKIE[$getvariables[$count]];
    $count++;
  }
}

if ($cpuloadmonitor) {
  $myshelldata = shell_exec("uptime");
  $myshelldata = eregi_replace(".*average.*: ","",$myshelldata);
  $myshelldata = eregi_replace(", .*","",$myshelldata);
  if ($myshelldata >= $cpumaxload) {
    echo "<b><h1>Access Denied</h1><br><br>The server is currently too busy to serve your request.  We apologize for the inconvenience.</b>";  
    exit();
  }
  unset($myshelldata);
}

unset($count);
unset($getvariables);
unset($ip);
unset($cookiedomain);
unset($mykeyname);
unset($myposthashname);
unset($myhash);
unset($mysession);

$_SESSION["ccisec-errors"] = 0;
if (connection_aborted()) exit();

?>

Re: Vulnerable to spambots

PunBB doesn't rely on Javascript and it's going to stay that way wink
Not to mention that those scripts don't seem to help with spam per-se, the first script describes itself as:

Purpose: Base flood, XSS and SQL Injection protection

Re: Vulnerable to spambots

yes exactly, that way it can never be predicted/scripted
e.g. the admin supplys 20 human question and answer' sets (not mathematical equations) and they are randomly chosen each time someone registers

gil wrote:

I think that the "anti-captcha" should be personalised by the admin, and should not be a hard-coded question for example. Like a question and answer defined by the admin for example, but one can find another solution, I don't know.

Re: Vulnerable to spambots

Smartys wrote:

Bots can deal with activation emails though wink
And even if they couldn't, we already have an activation code process (and a cron job to remove unverified users after x days isn't difficult)

from what I've seen the spam bots do not have valid email addresses and would therefore not be able to receive the email with the uuid.  the uuid is different than generating the password on their side and posting the login info to the specific page without ever having received an email.  adding a cron job is about as much trouble as installing a mod, or extension.  a smarter process for verifying that a human is registering is the only thing I think needs to be implemented.  there are so many ways that that can be achieved without having to set up mods / extensions / custom work, so that joe nobody who doesnt know a thing about php / mysql or even the web, can download, upload and run punbb, and have a fairly obscure level of protection from spam bots.  instead of finding ways to keep from writing this (I'm a software engineer, and I understand disagreeing with the users of your software, and trying to force them to see your point of view, so please don't think I'm trying to be rude when I say this, because I know where you're coming from), if you spent as much time thinking of a new registration process that would do what people want and be as non-disruptive as possible as has been spent explaining to people why captcha is snake oil, I think we all could have out of the box installs that are 90 something percent spam free.

Re: Vulnerable to spambots

from what I've seen the spam bots do not have valid email addresses and would therefore not be able to receive the email with the uuid

Then how do they get past email validation now? wink

the uuid is different than generating the password on their side and posting the login info to the specific page without ever having received an email.

Yes. But as I've said, PunBB already has email validation. Bots simply use disposable email sites if they need.

adding a cron job is about as much trouble as installing a mod, or extension.

No, since while anyone who runs PunBB can edit a file, not everyone has access to crontab on their server

a smarter process for verifying that a human is registering is the only thing I think needs to be implemented.  there are so many ways that that can be achieved without having to set up mods / extensions / custom work, so that joe nobody who doesnt know a thing about php / mysql or even the web, can download, upload and run punbb, and have a fairly obscure level of protection from spam bots.

Such as? wink

instead of finding ways to keep from writing this (I'm a software engineer, and I understand disagreeing with the users of your software, and trying to force them to see your point of view, so please don't think I'm trying to be rude when I say this, because I know where you're coming from), if you spent as much time thinking of a new registration process that would do what people want and be as non-disruptive as possible as has been spent explaining to people why captcha is snake oil, I think we all could have out of the box installs that are 90 something percent spam free.

If I were trying to find ways to keep from writing code, I wouldn't have agreed to be a PunBB developer and I certainly wouldn't have written/integrated 3 anti-spam tools for PunBB 1.2 on a Saturday. tongue
I'm open to suggestions and I'm certainly thinking of ways to deal with the issue of spam, but we have to keep in mind that spammers will try to cope, as they always do. The "add questions to registration" idea, for example, is interesting (and certainly worthy of an extension), but all it takes for a spammer to get around it is a little human interaction (which spammers are willing to pay people for).
And in the end, having a more modular approach to fighting spam allows people to use the tools they want as opposed to having certain tools forced upon them.

63

Re: Vulnerable to spambots

Just FYI.

There is apparently a very effective yet simple mod that is available for phpBB discussed here:

http://www.phpbb.com/community/viewtopic.php?t=435702

It works by allowing the admin to specify a 'VIP code' or pass-phrase, essentially, that users need to enter when they register. The variability of this across phpBB boards makes it effective against scripted bots.

Judging from the feedback in the thread above, it seems to work well. Some forum admins even report being able to turn off their CAPTCHAs.

It's similar to some of the approaches already discussed here.

Re: Vulnerable to spambots

sirena wrote:

Just FYI.

There is apparently a very effective yet simple mod that is available for phpBB discussed here:

http://www.phpbb.com/community/viewtopic.php?t=435702

It works by allowing the admin to specify a 'VIP code' or pass-phrase, essentially, that users need to enter when they register. The variability of this across phpBB boards makes it effective against scripted bots.

Judging from the feedback in the thread above, it seems to work well. Some forum admins even report being able to turn off their CAPTCHAs.

It's similar to some of the approaches already discussed here.

It's like the question method people have been discussing. smile
However, once enough people start using a tool to fight spammers, the spammers try to adapt. If there's a way to detect what the word is, for example, they'll do it.

65

Re: Vulnerable to spambots

However, once enough people start using a tool to fight spammers, the spammers try to adapt. If there's a way to detect what the word is, for example, they'll do it.

Of course you are right there.

But from the [long] discussion in that thread, it is pretty clear that people have grokked that personalisation of the way this mod works is key to its success. There are lots of interesting variations discussed. I think the approach as some promise for punBB.

If I wasn't a such a PHP dumbo, I'd have a go at adapting the phpBB mod for punBB myself smile

I like its simplicity and apparent robustness, even against human spammers sometimes it seems.

Re: Vulnerable to spambots

Smartys wrote:

from what I've seen the spam bots do not have valid email addresses and would therefore not be able to receive the email with the uuid

Then how do they get past email validation now? wink

good question.  maybe we should ask one of the punbb developers?

Re: Vulnerable to spambots

MadHatter wrote:
Smartys wrote:

from what I've seen the spam bots do not have valid email addresses and would therefore not be able to receive the email with the uuid

Then how do they get past email validation now? wink

good question.  maybe we should ask one of the punbb developers?

Now where would we find one of those... oh, wait! big_smile
I'll answer then: they use legit emails (usually disposable accounts that get deleted soon after), read the emails, and grab the passwords from them.

68 (edited by MadHatter 2007-05-21 01:16)

Re: Vulnerable to spambots

this is the only thing that I'd have to reproduce on my side if I wanted to sign up with an invalid email.

//
// Generate a random password of length $len
//
function random_pass($len)
{
    $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';

    $password = '';
    for ($i = 0; $i < $len; ++$i)
        $password .= substr($chars, (mt_rand() % strlen($chars)), 1);

    return $password;
}

now, if by stark contrast I use a globally / universally unique identifier from the database, then what I'd have to produce on my end in order to "fake" a email validation is to reproduce the uuid that was generated when I signed up in whoever's database I was trying to spam...

when I delete these accounts I research the domains that the emails use, and 100% of them do not exist.   yea they could sign up with one email, sign in, and change it, then post spam, but that type of critical thinking might lead to some sort of progress in the way of fixing the issue and is therefore dangerous.

at the very least, adding logging to the forum for actions like registration, password, and email changing would help narrow down the point of attack, and would allow you to "fix" the area of exploitation.

Re: Vulnerable to spambots

MadHatter wrote:

this is the only thing that I'd have to reproduce on my side if I wanted to sign up with an invalid email.

//
// Generate a random password of length $len
//
function random_pass($len)
{
    $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';

    $password = '';
    for ($i = 0; $i < $len; ++$i)
        $password .= substr($chars, (mt_rand() % strlen($chars)), 1);

    return $password;
}

Indeed: now, tell me how you plan on generating the password you were assigned from that? The whole point of it is that it's generated randomly wink

MadHatter wrote:

when I delete these accounts I research the domains that the emails use, and 100% of them do not exist.   yea they could sign up with one email, sign in, and change it, then post spam, but that type of critical thinking might lead to some sort of progress in the way of fixing the issue and is therefore dangerous.

I'm not quite sure what you're getting at to be honest
Out of curiosity though, what forum(s) are you referring to?

MadHatter wrote:

at the very least, adding logging to the forum for actions like registration, password, and email changing would help narrow down the point of attack, and would allow you to "fix" the area of exploitation.

What kind of logging would you propose adding and how would it help?

70 (edited by MattF 2007-05-21 01:47)

Re: Vulnerable to spambots

No matter what technology, if any, is implemented, the bot scripters will adapt their software. This has happened in all areas where restrictions are applied. I'll make an example of SMTP servers. You look through any mailing list archives around eighteen months ago regarding smtp transaction rejection messages and e-mail addresses contained therein, and the emphatic answer would have been that bots do not parse those messages. Nowadays, they do. One has to remember that some of these bots are not merely some bored teenager writing a bot after they get home from school, just as an exercise in coding. Some of these things are written by people who are making a small fortune from the spam they propogate, and will not let some minor attempt at thwarting it stop them. Whatever you can throw at them to block it, they will find a multitude of ways to circumvent it.

71 (edited by sirena 2007-05-21 03:13)

Re: Vulnerable to spambots

MattF said:

Whatever you can throw at them to block it, they will find a multitude of ways to circumvent it.

Only if it is 'cost-effective' for them to do so.

That's the big issue with all forms of spam - comment spam, forum spam, web spam, and email spam. The financial yield can be quite high even with relatively low response rates because the 'cost' of flooding the market is quite low if you have the right tools and know the technology. Even if you only get a 1% response rate to the 1 million spam emails you sent out, it is still worth doing because the costs of generating those emails can be quite low.

Change the landscape, however, by introducing a higher level of technological 'friction' or legal/financial risk into the business of spam, and you change the cost/benefit ratio of all forms of spam, and thus the incentives to perform it.

Hence my enthusiasm for things like the 'no-follow' tag and forum spam options like the afore-mentioned 'VIP code' mod. They introduce friction into the spam process and alter the cost/benefit ratio for forum spammers.

72 (edited by MattF 2007-05-21 04:10)

Re: Vulnerable to spambots

If you modded your installation to use that method, it probably would kill your spam off either completely or to a negligible level. However, was not the point of this thread with regards to including standard spam prevention techniques within PunBB? If, for example, that mod was incorporated within 1.3 when it finally leaves R.C status, the thing would be cracked within a week. It is then not a deviant technology, but a core mainstream one. The fiscal benefit for the bot scripters would mean that it was viable to concentrate on it once that occured.

Re: Vulnerable to spambots

Smartys wrote:
MadHatter wrote:

this is the only thing that I'd have to reproduce on my side if I wanted to sign up with an invalid email.

//
// Generate a random password of length $len
//
function random_pass($len)
{
    $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';

    $password = '';
    for ($i = 0; $i < $len; ++$i)
        $password .= substr($chars, (mt_rand() % strlen($chars)), 1);

    return $password;
}

Indeed: now, tell me how you plan on generating the password you were assigned from that? The whole point of it is that it's generated randomly wink

MadHatter wrote:

when I delete these accounts I research the domains that the emails use, and 100% of them do not exist.   yea they could sign up with one email, sign in, and change it, then post spam, but that type of critical thinking might lead to some sort of progress in the way of fixing the issue and is therefore dangerous.

I'm not quite sure what you're getting at to be honest
Out of curiosity though, what forum(s) are you referring to?

MadHatter wrote:

at the very least, adding logging to the forum for actions like registration, password, and email changing would help narrow down the point of attack, and would allow you to "fix" the area of exploitation.

What kind of logging would you propose adding and how would it help?

you're right...
there's no better way than whats been implemented. 
nothing else anyone can do outside of whats been done. 
if you want your official punbb forum, you just have to deal with the spam.

glad I finally figured that out.  I'm a bit slow so you'll have to forgive me (us) for thinking all this massive spam is a problem.

please continue (not) developing the next version.

74 (edited by MattF 2007-05-21 05:51)

Re: Vulnerable to spambots

MadHatter wrote:
smartys wrote:
MadHatter wrote:

at the very least, adding logging to the forum for actions like registration, password, and email changing would help narrow down the point of attack, and would allow you to "fix" the area of exploitation.

What kind of logging would you propose adding and how would it help?

you're right...
there's no better way than whats been implemented. 
nothing else anyone can do outside of whats been done. 
if you want your official punbb forum, you just have to deal with the spam.

glad I finally figured that out.  I'm a bit slow so you'll have to forgive me (us) for thinking all this massive spam is a problem.

please continue (not) developing the next version.

That was a really useful response, wasn't it. What type of logging? How can you log an exploit that isn't an exploit?

75

Re: Vulnerable to spambots

Smartys wrote:
sirena wrote:

Just FYI.

There is apparently a very effective yet simple mod that is available for phpBB discussed here:

http://www.phpbb.com/community/viewtopic.php?t=435702

It works by allowing the admin to specify a 'VIP code' or pass-phrase, essentially, that users need to enter when they register. The variability of this across phpBB boards makes it effective against scripted bots.

Judging from the feedback in the thread above, it seems to work well. Some forum admins even report being able to turn off their CAPTCHAs.

It's similar to some of the approaches already discussed here.

It's like the question method people have been discussing. smile
However, once enough people start using a tool to fight spammers, the spammers try to adapt. If there's a way to detect what the word is, for example, they'll do it.

Of course, but How? If it is not hard-coded, if it is different in each forum, and if it can be changed by the admin when he want to do? Only human action can help spambot, scripting isn't sufficient it seems.  If a large forum is a specific target for some spammer, of course a human help will be used. But all the small or medium forums (99%) will be protected!
I totally agree with Sirena and it "cost-effective" contribution...