[PHP] Badword-Filter - Hilfe

TTlong

Angesehenes Mitglied
Hallo,

ich will mir einen Badword-Filter basteln, weiss aber net, wie ich prüfen soll, ob ein "Badword" in der übergebenen Variable (Zeichenkette) vorhanden ist.

$badword = // Werte aus DB
$text = // per POST übergebener Wert

Kann jemand weiter helfen?


Danke und Gruß TTlong
 
Ich würde statt str_replace eher auf str_ireplace setzen, weil case-insensitive
 
naja ganz so einfach könnt ihr euch das auch nicht machen.
denn oft werden ja bad-words mit sonderzeichen kodiert also statt viagra schreibt man via*gra

daher würde ich erstmal ein preg_replace über den string jagen wo sämtliche sonderzeichen entfernt werden.
danach dann str_word_count um die dortanzahl zu zählen
str_word_count kann dir dann den string als wortarray zurückgeben dann ein
in_array() wo treffer mitzählen

dann nen kleinen 3satz um den prozentsatz der badwords rauszubekommen
dann ne kleine switchanweisung

0% allet paleti
1-3% spam verdacht
>3% spam string in db sperren bis zur manuellen prüfung
smile.gif



so ungefähr könnte es aussehen
 
Danke für eure Antworten.

Das ganze ist für mein SMS Script. Mit str_word_count hab ich bereits eine seperate Sperre, die verhindert, dass zu wenig Wörter verschickt werden. Nun soll das alles auch noch nach nicht erlaubten Wörter durchforstet werden.

Sollte ein derartiges Wort im Text gefunden werden, wird die entsprechende IP in die Tabelle mit den geblockten IP's geschoben und hat dann keinen Zugriff mehr auf das Script.

Brauche im Prinzip nicht schauen, ob dort noch Sonderzeichen drin sind, die kann ich ja dann entsprechend in die Blacklist eintragen.

Schau mir jetzt mal preg_* und str_ireplace an.
 
So, hab jetzt was zusammengebastelt was funktioniert (wenns noch jemand gebrauchen kann):

QUOTE $ergebnis = mysql_query("SELECT words FROM xxx_badword");
  while($row = mysql_fetch_array($ergebnis))
    {
$badwords=$row["words"];

$badword = array($row["words"]);
$text = $HTTP_POST_VARS[text];

foreach($badword as $forbidden){
$ok = substr_count($text, "$forbidden");
if($ok>0){
$pos = strpos($text, "$forbidden");
$monl = strlen($forbidden);
$mon = substr($text, $pos, $monl);

mysql_query("INSERT INTO xxx_blocked (blocked_ip, ...) VALUES ('$ip', ...)");
    }
  }
}


Falls noch wer nen Verbesserungsvorschlag hat, immer her damit.

Gruß TTlong
 
Ich habe zwar noch fast keine Erfahrung mit solchen Badword-Filtern.

Allerdings macht dein Code das, was man normalerweise nicht machen soll: Du holst pro Fall die Daten (hier: Badwords) und gehst sie in einer Schleife durch. Damit stehen typische Datenbank-Techniken nicht zur Verfügung - normalerweise sollten diese (1) grundsätzlich performanter sein, (2) das 'Herausholen' der Daten (jedesmal) ließe sich vermeiden.

Beispiel (wird bei server-daten in ähnlicher Form eingesetzt: Dort sind in benutzerdefinierten Abfragen bestimmte MS-SqlServer-Schlüsselwörter verboten):

CODE Select Top 1 A.id
From badwords As A
Where @inputString Like '%' + A.badword + '%'


@inputstring wird mit der zu prüfenden Zeichenfolge belegt.

Auf diesem Level stimmt das nicht ganz, da auch ein Badword als Teil eines größeren Wortes erkannt wird (was u.U. falsch sein könnte). Bei server-daten ist eine Wortzerlegung vorgeschaltet, so daß jedes Wort in einer eigenen Zeile drinsteht. Dann stimmt das exakt, dann läßt sich das sogar direkt über einen Join machen.

Allerdings reicht die obige Methode bei Badwords aus - da will man ja auch Wortbestandteile killen.

Vorteil 1: Die Wortliste muß nicht erst rausgeholt werden.
Vorteil 2: Normalerweise sind Sql-Anweisungen, die auf Mengen operieren, effizienter als ein zeilenweises Abarbeiten.

Im Prinzip mußt Du bloß gucken, ob diese Abfrage eine Zeile zurückgeliefert hat.

PS: Nachträglich muß ich natürlich feststellen: Ich habe doch schon Erfahrung damit
biggrin.gif
 
Ausserdem braucht man keine Regexes, um zu schauen, ob sich ein wort in einem string befindet. Meines Wissens reicht eregi() vollkommen aus.

CODE
eregi($badword, $zeichenkette);

 
QUOTE Note: preg_match(), which uses a Perl-compatible regular expression syntax, is often a faster alternative to ereg().


eregi ist total veraltet! ausderdem benutzt ereg genauso regular expressions.
 
QUOTE (jAuer @ Do 31.01.2008, 19:51) Beispiel (wird bei server-daten in ähnlicher Form eingesetzt: Dort sind in benutzerdefinierten Abfragen bestimmte MS-SqlServer-Schlüsselwörter verboten):


CODE Select Top 1 A.id
From badwords As A
Where @inputString Like '%' + A.badword + '%'


@inputstring wird mit der zu prüfenden Zeichenfolge belegt.

Auf diesem Level stimmt das nicht ganz, da auch ein Badword als Teil eines größeren Wortes erkannt wird (was u.U. falsch sein könnte). Bei server-daten ist eine Wortzerlegung vorgeschaltet, so daß jedes Wort in einer eigenen Zeile drinsteht. Dann stimmt das exakt, dann läßt sich das sogar direkt über einen Join machen.

Allerdings reicht die obige Methode bei Badwords aus - da will man ja auch Wortbestandteile killen.



jAuer,

man könnte erst Deinen Code anwenden,
dann mit explode den InputString in ein Array der einzelnen Worte zerlegen und dann prüfen ob das Trefferwort in dem Array ist. Dann wäre es immer noch performant aber es würden keine Wortbestandteile erkannt sondern nur volle Wörter


Anderer Punkt. Ist es wirklich sinnvoll die Badwords als einzelne Zeilen in der Tabelle zu halten?
Einen String der sie alle enthät könnte ich schnell aus der Datenbank einlesen (dann in Array zerlegen), alle weiteren Operationen dann im Speicher. Oder nicht?
 
Hallo an alle,

ich bin kein Progger, darum weiss ich auch nicht, ob der Quelltext stimmt oder das, was er angeblich tun soll, auch macht!!!

Ich habe das hier auf Homepage-Forum.de gesehen:

QUOTE Einsatzgebiet:
private Gästebücher in deutscher Sprache

Funktionsweise:
Prüft die Eingaben in der Textarea nach den gängigsten Wörtern der Spammer.

Features:
Rauswurf aus dem Gästebuch nach einer angegebenen Menge an Fehlversuchen.

Es sind insgesamt 3 Schritte notwendig.

1. Schritt
Ergänzung des Formulares um 2 versteckte Felder.
Einfach an das Ende des Formulares kopieren.
HTML-Code:


QUOTE <input type="hidden" name="pruefung" value="<? echo $pruefung;?>">
<input type="hidden" name="eintragen" value="1" />


Das 1. Element zählt die Fehlerversuche beim abschicken des Formulares
Das 2. Element ist eine Kontrollvariable zum Ausführen des eigentlichen Codes

An die gewünschte Stelle im HTML-Bereich den folgenden Code setzen.
Er gibt den Hinweistext aus, wenn Spam erkannt wurde.
PHP-Code:


QUOTE <?php echo $spamtext; ?>


2. Schritt
Nun muß der Ursprüngliche Code des Gästebuches in eine weitere Abfrage gesetzt werden.

PHP-Code:


QUOTE if ($eintragen == 1)
{
eigentlicher Code
}


3. Schritt
Den folgenden Code an den Anfang der Seite kopieren, noch bevor die HTML Auszeichnung beginnt.
Anpassen des Namens der Textarea und evtl. die Rauswurf_url.

PHP-Code:


QUOTE if (isset($_POST["pruefung"]))
{
// Postvariablen aufarbeiten
$pruefung = $_POST["pruefung"];
$eintragen = $_POST["eintragen"];
// Hier den Namen der Textarea anpassen
// nur rechts im $_POST-Bereich das Wort message ersetzen
$message = stripslashes($_POST["message"]);
// Nach wieviel Fehlversuchen soll der Schreiber rausgeworfen werden ?
// Der Poster hat z.B. 3 Fehlversuche, beim 4. geht es ab.
// Das greift nur, wenn im Text ein Wort aus der Badword Liste vorhanden ist.
$rauswurf = 3;
// Wohin soll er rausgeworfen werden ?
$url_rauswurf = "http://www.antispam.de/";
// Hinweistext für den Spammer
$spamhinweis = "No Spam please !!!";
// Die Liste kann beliebig erweitert werden
$badwords = "thanks,good,great,thank,tnx,look,looking,perfect,very,nice,gay";


// Rauswurf wenn oben angegebene Menge an Postings erreicht wurde
if ($pruefung == $rauswurf): header("location:".$url_rauswurf.""); endif;
$wordtest = explode(",",$badwords);
foreach ($wordtest as $value)
{
if (stristr($message,$value)):
$eintragen = 0;
$spam = 1;
endif;
}
if ($spam == 1):
if (empty($pruefung)) $pruefung = 1; else $pruefung = bcadd($pruefung,1,0);
$spamtext = $spamhinweis;
endif;
} // Ende $_POST["pruefung"]


Das war es auch schon.
Wenn es nach dem Einbau Fehlermeldungen gibt, liegt es wahrscheinlich an einem Fehler in der Klammersetzung.

Die Badword Liste ist nur ein kleiner Baustein zu einem Spamsicheren Gästebuch, aber immerhin ein erster Schritt der schon eine Menge bringt.
Der Einsatz ist nur sinnvoll, wenn man ansonsten keine englischen Einträge hat.

Ich habe auf 2 verschiedenen HP´s dasselbe GB im Einsatz.
Eines mit und eines ohne diese Liste.
Das eine wird weiter zugespammt und beim anderen hatte ich seitdem nicht einen einzigen Spameintrag.

Dieses Script ist auch problemlos im Kontaktformular einsetzbar.


Quelle: [Tutorial | PHP] Badword Liste für Gästebuch - Homepage-Forum.de geschrieben von Marco >> User auf Homepage-Forum.de

Meine Frage: kann man das auch Umschreiben für ein Forum? Oder kann man das hier 1:1 übernehmen?

Vielleicht ist es ja auch ein Denkanstoss für andere.

besten Gruss Björn

PS: als Anregung für Bad-Words: Schimpfwoerter.de

Nachtrag: hier sind mal 2 Listen. Nur Überflogen, keine Ahnung, ob sie was wert sind:

http://www.analytictech.com/mb870/bwfldata.htm

http://www.delphipraxis.net/topic37248.html
 
QUOTE (Björn Kaiser @ Do 14.02.2008, 23:34) PS: als Anregung für Bad-Words: Schimpfwoerter.de



Björn, dazu aus dem Impressum der Seite:
alle darauf enthaltenen Informationen, Texte, Bilder, Videos, etc. sind urheberrechtlich geschützt!


QUOTE
Nachtrag: hier sind mal 2 Listen. Nur Überflogen, keine Ahnung, ob sie was wert sind:

http://www.analytictech.com/mb870/bwfldata.htm

http://www.delphipraxis.net/topic37248.html



Das sind leider englische Wortlisten. Bräuchte eine deutsche.

Kennt vielleicht einer eine kostenlose Forensoftware in der bereits eine deutsche Wortliste badwords enthalten ist (die Forensoftware brauche ich nicht, wäre für mich nur wegen der Wortlist interessant).

 
QUOTE Björn, dazu aus dem Impressum der Seite:
alle darauf enthaltenen Informationen, Texte, Bilder, Videos, etc. sind urheberrechtlich geschützt!


das soll also heissen, wenn ich hier jetzt "Steckdosenbefruchter" schreibe, verstosse ich gegen ein Urhebergesetz?

das kann ich mir dann doch nicht vorstellen. Ausserdem soll es ja nur eine Anregung sein, auf welche Bad-Words manche kommen mit ihrer Fantasie.

Zu deiner Suche: ich glaube kaum, das man eine deutsche Liste findet, die würde wahrscheinlich nicht mal Alain rausrücken
wink.gif


Gruss Björn
 
QUOTE (Björn Kaiser @ Fr 15.02.2008, 01:07)
Zu deiner Suche: ich glaube kaum, das man eine deutsche Liste findet, die würde wahrscheinlich nicht mal Alain rausrücken
wink.gif




Du schätzt Alain völlig falsch ein.
Ich kann aus eigener Erfahrung sagen, dass er seeeeehr hilfsbereit ist.
 
Dann frag ihn doch. Seine Liste dürfte bestimmt auch schon 300-400-500 Worte enthalten.

Das Alain hilfsbereit ist, weiss ich selbst. Nur wenn so eine Liste mal im Umlauf ist und man weiss, wo sie eingesetzt wird, dann kann man sehr schnell Mist damit bauen.

Das meinte ich damit: solche Listen sind ja schon fast wie der "Heilige Gral" und somit Top Secret.
Und wenn sie so einfach zu haben wären, dann müsste man sie ja bei der dicken Tante recht einfach finden.
 
Zurück
Oben