5 Anti-Spam-Maßnahmen für phpBB 3.0

Note: There is an up­dated Eng­lish ver­sion of this blog post avail­able.

phpBB ist als Foren-Soft­ware mit of­fenem Quellcode sehr be­liebt und weit ver­breitet. Aus diesem Grund ist es aber auch häufig das Ziel von Spam­mern. In der Ver­sion 3.0 wurde de­shalb unter an­derem ein besseres Captcha einge­führt. Leider haben sich die Spam­mer in­zwis­chen auf die neue Ver­sion einges­tellt und Bots ges­chrieben, die das Captcha auto­mat­isch über­winden und Beiträge ab­set­zen können. Im Fol­genden wer­den de­shalb fünf Anti-Spam-Maß­nah­men bes­chrieben, die sich in jeder phpBB-3.0-In­stall­a­tion ein­set­zen lassen und sehr ef­fektiv sind. Ziel ist es dabei, mög­lichst viele Spam-Beiträge zu block­ieren ohne den nor­malen Be­trieb des For­ums zu bee­in­trächti­gen.

Spam­mer ver­suchen meist bestim­mte Web­sites zu be­w­er­ben. De­shalb en­thal­ten etwa 95% al­ler Spam-Beiträge Links bzw. URLs. Die ef­fekt­ivste Meth­ode sol­che Beiträge zu ver­hindern, ist Links kom­plett zu sper­ren. Da die hier vorges­tell­ten Maß­nah­men nor­male Be­n­utzer aber mög­lichst wenig bee­in­trächti­gen sol­len, kann ein kleiner Trick ver­wen­det wer­den: Es wird davon aus­gegan­gen, dass ein Spam­mer sich in einem Forum neu an­mel­det und direkt damit be­ginnt, Wer­be­botschaften zu schreiben. Das heißt, Gäste und Be­n­utzer mit weni­ger als einer bestim­mten Zahl von Beiträ­gen wer­den als po­ten­zi­elle Spam­mer be­han­delt. Ihre Beiträge wer­den genauer un­ter­sucht. Alle an­deren Be­n­utzer bleiben von den Maß­nah­men un­be­tro­f­fen.

Um Beiträge mit Links zu block­ieren, kann die Funk­tion submit_post() in der Datei includes\functions_posting.php um fol­gende Zei­len er­gänzt wer­den:

//Define the minimum number of posts for "good" users
//Users below this threshold are considered potential spammers
$user_posts_threshold = 3;

//strip whitespace characters in the post body
$msgwows = $data['message'];
$msgwows = str_replace(" ", "", $msgwows);
$msgwows = str_replace("\n", "", $msgwows);
$msgwows = str_replace("\r", "", $msgwows);
$msgwows = str_replace("\t", "", $msgwows);

if (!$user->data['is_registered'] ||
    $user->data['user_posts'] < $user_posts_threshold) {
  if (strpos($msgwows, 'http://') !== FALSE ||
      strpos($msgwows, 'ftp://') !== FALSE ||
      strpos($msgwows, 'www.') !== FALSE ||
      strpos($msgwows, '[url') !== FALSE) {
    trigger_error("You are not allowed to post URLs!");
  }
}

Dieser Code sollte selb­stver­ständ­lich ganz am An­fang der Funk­tion stehen, damit die Beiträge vor dem Speich­ern ge­fil­tert wer­den.

Maßnahme 2: Bilder

Spam­mer ver­suchen Fil­ter of­t­mals durch den Ein­satz von Bildern zu umge­hen. Dazu schreiben sie ihre Wer­be­botschaften und Links in Bild­dateien und hän­gen diese an Foren-Beiträge an. Mit dem gleicher Meth­ode wie oben bes­chrieben, können in der Funk­tion submit_post() in der Datei functions/functions_posting.php Beiträge mit Bildern geb­lockt wer­den:

if (!$user->data['is_registered'] ||
    $user->data['user_posts'] < $user_posts_threshold) {
  if (strpos($msgwows, '[img') !== FALSE) {
    trigger_error("You are not allowed to post images!");
  }
}

Maßnahme 3: Russische und Chinesische Beiträge?

Ein­ige Spam-Beiträge sind auf Russ­isch oder Chin­es­isch oder en­thal­ten ein­fach nur eine Menge un­leser­licher Son­derzeichen. Man kann sich zunutze machen, dass in deutsch- und eng­lischs­prac­hi­gen Foren in der Re­gel nur Deutsche bzw. Eng­lische Beiträge er­wün­scht sind. Beiträge mit sehr vielen Son­derzeichen bzw. Zeichen aus frem­d­sprac­hi­gen Al­pha­beten können prob­lem­los als Spam be­trachtet wer­den.

Cory Mawhorter hat eine kleine PHP-Funk­tion ver­öf­fent­licht (is_english()), die auf ein­fache Weise Son­derzeichen erkennt. Diese kann ver­wen­det wer­den, um Deutsche bzw. Eng­lische Texte von frem­d­sprac­hi­gen zu un­ter­scheiden:

if (!$user->data['is_registered'] ||
    $user->data['user_posts'] < $user_posts_threshold) {
  if (!is_english($msgwows, 0.75)) {
    trigger_error("Only German or English posts are allowed here!");
  }
}

Maßnahme 4: http:BL

Das Pro­ject Honey Pot bi­etet ein ef­fekt­ives Sys­tem an, um Spam­mer und Ad­ress­sammler von Web­seiten fern zu hal­ten. http:BL gleicht die IP-Ad­resse eines Be­such­ers mit einer Daten­bank ab. Ist die IP-Ad­resse bekannt und ver­birgt sich dah­inter ein Spam­mer, dann kann der Be­sucher schon ges­perrt wer­den be­vor er die Web­seite sieht. Das Sys­tem ver­wen­det DNS, wodurch die Ab­fra­gen re­lativ schnell sind.

Um http:BL zu ver­wenden, muss man sich bei Pro­ject Honey Pot re­gis­tri­eren. Dadurch er­hält man einen Schlüs­sel, der dem ei­genen Be­n­utzer­na­men eindeutig zugeord­net ist. Pro­ject Honey Pot will dadurch Miss­brauch des Sys­tems ver­hindern. Ein MOD für phpBB wird an­ge­boten, al­lerd­ings nur für Ver­sion 2.0. Diesen kann man unter Um­ständen an phpBB 3.0 an­passen. Al­tern­ativ kann man fol­genden Code an das Ende der Datei common.php kopieren:

//configure your http:BL Access Key here
$httpblkey = "xxxxxxxxxxx";
$httpblmaxdays = 21;
$httpblmaxthreat = 25;

//if you already configured a honey pot on your website use this line:
//$httpblhoneypot = "http://xxxxxxxxxxx";

function httpbl_check() {
  global $httpblkey, $httpblmaxdays, $httpblmaxthreat, $httpblhoneypot;

  $ip = $_SERVER["REMOTE_ADDR"];

  $result = explode(".", gethostbyname($httpblkey."."
    .implode(".", array_reverse(explode(".", $ip)))
    .".dnsbl.httpbl.org"));

  if ($result[0] != 127) {
    //something went wrong or the IP is not in the database.
    //ignore this one.
    return;
  }

  $days = $result[1];
  $threat = $result[2];

  if ($days < $httpblmaxdays && $threat > $httpblmaxthreat) {
    if ($httpblhoneypot) {
      header("HTTP/1.1 301 Moved Permanently");
      header("Location: ".$httpblhoneypot);
    }
    die();
  }
}
httpbl_check();

In der Vari­ablen $httpblkey muss der http:BL Ac­cess Key an­gegeben wer­den.

Maßnahme 5: Akismet

Eine weit­ere Meth­ode Spam zu block­ieren, ist Akismet. Dieses Sys­tem wird auch gerne in Word­Press-Blogs einge­setzt. Wie für Pro­ject Honey Pot, benötigt man hier­für einen API-Key, den man durch eine Re­gis­tri­er­ung er­hält.

In Foren kann Akismet zum Beis­piel beim Ab­senden von Beiträ­gen ver­wen­det wer­den. Das Sys­tem kann zu Falschmel­dun­gen führen, we­shalb die Fil­ter­ung auch hier wieder nur auf die er­sten Beiträge eines Be­n­utzers bes­chränkt wird. Der fol­gende Code ver­wen­det die Datei Akismet.class.php, die man von Alex Pot­sides’ Git­Hub-Re­pos­it­ory her­unter­laden kann. Der Code kann in die Funk­tion submit_post() in der Datei includes/functions_posting.php einge­fügt wer­den:

//configure your Akismet API key here
$akismet_key = 'xxxxxxxxxxx';

//the URL you entered when you registered for a Wordpress account
$akismet_url = 'xxxxxxxxxxx';

include('Akismet.class.php');

$akismet = new Akismet($akismet_url, $akismet_key);
if (!$user->data['is_registered'])
  $akismet->setCommentAuthor($username);
else
  $akismet->setCommentAuthor($user->data['username']);
$akismet->setCommentContent($data['message']);
$akismet->setUserIP($user->ip);
if ($user->data['is_registered'])
{
  $akismet->setCommentAuthorEmail(strtolower($user->data['user_email']));
  $akismet->setCommentAuthorURL(strtolower($user->data['user_website']));
}

if ((!$user->data['is_registered'] ||
    $user->data['user_posts'] < $user_posts_threshold) &&
    $akismet->isCommentSpam()) {
    trigger_error("Akismet says your post is spam");
}

Die Vari­able $akismet_key muss den Akismet API Key en­thal­ten. Die URL, die man bei der Re­gis­tri­er­ung für einen Word­Press-Ac­count an­gegeben hat, muss in der Vari­ablen $akismet_url stehen.

Akismet kann des­weit­eren sin­nvoll bei der Re­gis­tri­er­ung von neuen Be­n­utzern einge­setzt wer­den. Dazu ist fol­gender Code in die Funk­tion user_add() in der Datei includes/functions_user.php ein­zufü­gen:

//configure your Akismet API key here
$akismet_key = 'xxxxxxxxxxx';

//the URL you entered when you registered for a Wordpress account
$akismet_url = 'xxxxxxxxxxx';

include('Akismet.class.php');

$akismet = new Akismet($akismet_url, $akismet_key);
$akismet->setCommentAuthor($username_clean);
$akismet->setUserIP($user->ip);
$akismet->SetCommentAuthorEmail(strtolower($user_row['user_email']));

if($akismet->isCommentSpam()) {
  trigger_error("Akismet says you are a spammer");
}

Fazit

Die hier vorges­tell­ten Maß­nah­men helfen, das Spam-Aufkom­men in phpBB-3.0-Foren dras­tisch zu re­duzieren. Seit dem Akt­ivieren der ver­schiedenen Fil­ter im Spami­hil­ator-Forum kon­nte kein ein­zi­ger Spam­mer einen Beitrag ab­set­zen. Das Block­ieren von Links und Bildern ist dabei die ef­fekt­ivste Meth­ode. Durch das Fil­tern von Son­derzeichen wer­den alle an­deren Spam-Beiträge ver­hindert. Der nor­male Be­trieb wird kaum gestört, da die Maß­nah­men nur neue Be­n­utzer be­tref­fen. Sobald ein Be­n­utzer eine bestim­mte An­zahl von “guten” Beiträ­gen ges­chrieben hat, wer­den die Fil­ter deakt­iviert. Bisher hat dies noch kein Spam­mer aus­gen­utzt. Falls dies jemals der Fall sein sollte, kann die Schwelle sehr leicht er­höht wer­den.

Trotz al­ler Fil­ter­maß­nah­men beim Schreiben von Be­trä­gen, bleibt im­mer noch das Prob­lem, dass Spam­mer sich nach wie vor re­gis­tri­eren und in ihrer Sig­na­tur auf eine Web­seite ver­linken können. Maß­nah­men für dieses Prob­lem sind noch zu en­twick­eln.

In vielen von Spam ge­plagten Foren sind Gäste nicht zu­gelassen. Man muss sich re­gis­tri­eren, um Beiträge schreiben zu können. Dies kann für ein­fache Sup­port-Foren zu um­ständ­lich sein. Die Be­n­utzer möchten gerne Beiträge schreiben können ohne lange und kom­pliz­ierte Re­gis­tri­er­ungs­ver­fahren zu durch­laufen. Mit den in diesem Artikel vorges­tell­ten Maß­nah­men können Gäste grundsätz­lich wieder zu­gelassen wer­den, denn die Fil­ter­ung ist für sol­che im­mer aktiv.

Ab­schließend bleibt zu er­wähnen, dass der Ein­satz von Akismet auf deutschen Web­seiten zur Zeit noch um­strit­ten ist. Wei­t­eres darüber fin­det man unter an­derem in fol­gen­dem Artikel:

http://www.drweb.de/magazin/akismet-und-der-datenschutz/

Maß­nahme 5 kann bei Be­darf aus­gelassen wer­den.


Posted by Michel Krämer
on April, 8th 2009.