Ich habe da mal eine relativ sichere und einfache Flood-Kontrolle für viele Zwecke programmiert.
Man es dieses Script zum Beispiel einsetzen bei Gästebüchern, Foren, Countern, sonstigen Formularen,...
Es basiert auf PHP und MySQL, die Daten werden also in die Datenbank geschrieben.
Die Anzahl an maximalen Einträgen ist variablen, das heißt, dass man bestimmen kann, wie viele Einträge maximal in der DB stehen sollen.
Wenn also z.B. 10 eingestellt ist, dann überschreibt er immer die älteste und niedrigste ID und so geht es dann immer weiter...
Der Zeit-Intervall für die Flood-Kontrolle ist auch variabel. Man kann also einstellen, wie lange etwas nicht möglich sein kann (z.B. darf man nur alle 30
Sekunden in das Gästebuch schreiben, um Floodern keine Chance zu geben...)
Das Ganze funktioniert so:
- die Daten werden (z.B. über ein Formular eines Gästebuches) in die Datenbank eingetragen
- hier wird zuerst überprüft, ob die Anzahl der Einträge niedriger ist als vorgegeben
- falls sie das Limit erreicht hat, dann wird der älteste Eintrag gelöscht
- danach wird der neue Eintrag für den alten gespeichert
- falls die Anzahl niedriger ist, als vorgegeben, dann wird gleich eingetragen
- eingetragen wird immer eine ID (automatisch), der Zeitstempel und die IP-Adresse
- wenn die aktuelle IP-Adresse schon vorhanden ist, dann wird die neueste und höchste ID herausgesucht
- will man dann noch mal eintragen, so kommt die Meldung, dass man noch warten muss, bis der Zeit-Intervall vorbei ist
- ist dieser vorbei, kann man wieder eintragen und immer so weiter...
Das funktioniert auch eigentlich alles genau so, wie ich es mir vorstelle!
Nur gibt es da ein Problem:
Sobald das Limit für die maximale Anzahl an Datenbankeinträgen vorhanden ist (also in diesem Beispiel 10), dann überprüft er die Flood-Kontrolle nicht mehr,
sondern trägt einfach weiter ein und überschreibt aber die alten Einträge weiter.
Also das einzige Problem ist, dass er dann nicht mehr überprüft, ob schon eine IP vorhandne ist und wie lange das her war.
Warum? Ich sehe da keinen Grund dafür, außer vielleicht meine Abfrage für die Flood-Kontrolle, aber was ist daran falsch, ich sehe eigentlich nichts. Kann es
sein, weil ich immer die neueste ID heraussuche, dass es an dem liegt?
Hier noch der Quellcode des Scriptes:
<?php include('functions.inc.php'); db_connect(); $anzahl = 10; // Die maximale Anzahl an Einträgen in der Datenbank $zeit_intervall = 30; // Die Zeit (in Sekunden) für den Flood-Intervall $nowtime = time(); $nowip = get_ip(); $sql = @mysql_num_rows(@mysql_query("SELECT id FROM flood_kontrolle")); $flood = @mysql_fetch_array(@mysql_query("SELECT zeit FROM flood_kontrolle WHERE ip = '$nowip' ORDER BY id DESC LIMIT 1")); $site = (isset($_GET['site'])) ? $_GET['site'] : 'anzeige'; switch($site) { case 'anzeige': echo 'Einträge: <b>', $sql, '</b><br><br><a href="?site=eintrag_pruefen">Eintragen</a>'; break; case 'eintrag_pruefen': if($sql >= $anzahl) { $del = @mysql_query("DELETE FROM flood_kontrolle ORDER BY id LIMIT 1"); if($del == true) { header("Location: ?site=eintrag_abschicken"); } else { echo 'Es ist ein Fehler aufgetreten!'; } } elseif($nowtime - $flood['zeit'] < $zeit_intervall) { $zeit_warten = $zeit_intervall - ($nowtime - $flood['zeit']); echo 'Flood-Kontrolle aktiviert: Sie müssen mindestens <b>'.$zeit_intervall.' Sekunden warten!</b><br> Noch <b>'.$zeit_warten.'</b> Sekunden...<br><br> <a href="?site=anzeige">Zurück</a>'; } else { header("Location: ?site=eintrag_abschicken"); } break; case 'eintrag_abschicken': $db_eintrag = @mysql_query("INSERT INTO flood_kontrolle (zeit, ip) VALUES ('".time()."', '".get_ip()."')"); if($db_eintrag == true) { header("Location: ?site=anzeige"); } else { echo 'Es ist ein Fehler aufgetreten!'; } break; } ?>
Die Funktionen aus der "functions.inc.php" dienen nur zum Verbinden zur Datenbank und zur Ermittlung der IP-Adresse.
Wäre sehr nett, wenn mir jemand hift.
Anbei noch ein Link zu dieser Flood-Kontrolle (mal ohne Sinn, einfach nur so) und noch der Download mit allen PHP-Dateien und der SQL-Struktur:
Link zum Script
Download der Dateien