SPAM-Protection-Methoden Nr. 1: Honeypot
A leidiges Thema seit Anbeginn vom Internet is SPAM (na, ned des Dosenfleisch, des gibt's länger ois des Internet). An ana gelangweilten Wochenende hob i mir amoi a poar Gedanken gmacht, wia mia SPAM (alternativ a: Webcrawler) vameidn kinnan, und draus is die Reihe "SPAM protection methods" entstandn. Teil 1 dieser Reihe handelt vom Aussperrn nerviger SPAM-Bots von unserer Webseitn, kann aber a genutzt wern, um automatisierte Tools wia SiteSucker, aber a automatisierte Skripte via Chromium o. Ä. fernzuhoitn. Wia imma gilt - und do ganz besonders: Da Beitrag dient nur ois Anregung und soit ned unüberlegt 1:1 kopiert wern. Bei falscher Anwendung kann des Skript dazu führn, dass reguläre Nutzer von da Seitn ausgsperrt wern (z. B. dann, wenn's an Content-Preloader valwenden oda gor da Browser söba den Inhalt vorlodt).
1. Konzept
Grundsätzlich wolln mia im ersten Schritt den Bot erkennen und im zwoatn Schritt blockiern. Mei ursprüngliche Idee woar, den Bot über die htaccess-Datei zu blockiern. Sobois unser Skript an Bot erkennt, soit er ans End von da htaccess-Datei die Zeiln deny {IP} schreibn und so den Bot bzw. dessen IP-Adresse von unserer Seitn aussperrn. Idee guat, Umsetzung problematisch: Ois i gmerkt hob, dass des voraussetzt, dass i die .htaccess-Datei mit chmod beschreibbar mach, is mei Puls seltsamerweise auf an Bereich um 200 gstiegn. A Alternative muasst her, und de heißt "Sessions". Mia speichern ganz einfach den Status vom Nutzer in da Session und die gblockten IP-Adressen in ana Datenbank. Imma wenn a neicher Nutzer auf die Seitn kummt, schaun mia in da Datenbank noch, ob seine IP-Adresse gblockt is. Je nachdem kriagt er dann a Session-Variable zuagwiesn, de mia bei jedem Seitnaufruf prüfn kinnan und uns somit einige SQL-Abfragen sparn. Achtung: Nur Sessions reichen natürlich ned. Sonst hüft a einfaches Cookiedelete. Problematischer is es jedoch, überhaupt zu erkennen, ob's si um an Bot handelt oda ned. Mei Lösung woar bisher lediglich, an "hidden Link" einzufügn in da Form Ultra Fancy Link. A Spambot, der ned erkennen kann, ob da Link wirklich sichtbar is oda ned (weil für eam nur des href-Attribut relevant is, ned da style-Tag), ruft die target.php auf, in der si unser Honeypot befindet. Allerdings führte des dazu, dass Browser oda Plugins, de den Content teilweise precachen, die Seitn ebenfalls aufrufn und somit a a "normaler" Nutzer in unsern Honeypot geraten kann. Und des gilt es natürlich zu vameidn. Des Problem konnt i relativ einfach umgehn, indem i den Pfad https://example.com/target.php in die robots.txt gschriebn hob. Offensichtlich beachtn Browser, de Content precachen, die robots.txt (zumindest die Guatn), und so lasst si a "False Positive" vameidn. De target.php mocht jetzt nix ondres, ois die Datenbank mit da IP-Adresse vom Browser zu füttern.
2. Umsetzung
Schritt 1: Datenbank
Ois Erstes erstöin mia die Tabellen in da Datenbank:
CREATE TABLE `spamblock` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`ip` text,
`stamp` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
De Tabelle Spamblock enthoit jetzt die obligatorische Primary-ID, a Feld "ip", in des später die IP-Adresse eingtragn wird, ois a "stamp", des später den Timestamp enthoitn soi.
Schritt 2: target.php
Als Nächstes is die target.php dran (die kinnts ihr selbstverständlich a anders nennen). Die fügt amoi die IP-Adresse und den Timestamp in unsere Tabelle ein und setzt die Session-Variable.
<?php
$dbname = "dbname";
$username = "username";
$password = "password";
$pdo = new PDO("mysql:host=localhost;dbname=$dbname", $username, $password);
$ip = $_SERVER['REMOTE_ADDR'];
$stamp = time();
$stmt = $pdo->prepare("INSERT INTO spamblocked (ip, stamp) VALUES (:ip, :stamp)");
$stmt->bindParam(':ip', $ip);
$stmt->bindParam(':stamp', $stamp);
$stmt->execute();
?>
Natürlich miassn do dbname, username und password durch eure Daten ersetzt wern.
Schritt 3: Überprüfung von da Variable
Bei jedem Seitnaufruf muass jetzt überprüft wern, ob $_SESSION['spamblock'] true oda false is. Entweder mia auto-prependen jetzt des folgende Skript via htaccess: php_value auto_prepend_file "/var/www/virtual/david/check.php" (Achtung: Absoluter Pfad!) oda mia fügn folgende Zeiln an den Anfang von jeder Seitn ein:
<?php
session_start();
if (isset($_SESSION['spamblock']) && $_SESSION['spamblock'] === true) die();
?>
Hiermit prüfn mia, ob die Variable $_SESSION['spamblock'] gsetzt is und den Wert true enthoit. Wenn ja, beendn mia des Skript.
Schritt 4: Robots.txt
Als Nächstes fügn mia die target.php in unsere robots.txt ein, damit mia a koane "guatn" Crawler verschrecken und koane Probleme mit Precaching kriagn.
User-agent: *
Disallow: /target.php
Da Aufbau von da robots.txt soit selbsterklärend sei.
Schritt 5: Hidden Link oda sonstige Weiterleitung
Ois letzten Schritt fügn mia den Hidden Link in unsere reguläre Seitn ein, am besten so weit "vorn" wia möglich (index.php is guat, /unterseite/unterseite/unterseite/irgendeinfile.php is schlecht). Denn wenn da Crawler die ganze Seitn obgarbeitet hot und erst am End ausgsperrt wird, nachdem er seine Orbeit verrichtet hot, mocht des Ganze koan Sinn mehr. Alternativ kann ma a a Weiterleitung per Javascript machn. Möglichkeit oans wär des oben gnannte "display:none"-Attribut bei am Link.
<a href='target.php' style='display:none'>
Möglichkeit zwoa wär Javascript, wos allerdings voraussetzt, dass da Crawler Javascript deaktiviert hot (und Achtung: Sobois a regulärer Nutzer koa Javascript aktiviert hot, wird er ebenfalls ausgsperrt. Des do soi also eher a Denkanstoß sei ois a ernsthafte Lösung).
<noscript>
<iframe src="target.php"></iframe>
</noscript>
Sicherlich lasst si des Ganze no erweitern. Wenn ihr Ideen hobts, gern in die Kommentare haun.
Schritt 6: Abschließen
Schlussendlich lodn mia olle Dateien hoch, bereiten die Datenbank vor und hom im besten Foi in da insert.php die Werte "Username" und "Password" scho mit den Zugangsdaten zu unserer Datenbank ersetzt ;-)
Ergänzung: Adblocker nutzn
Wer no eins drauf setzn wü, kann den Adblocker nutzn, den heutzutage fost jeder Nutzer installiert hot, aber wohl kaum a Crawler. Mia benennen einfach die Datei target.php in subtarget.php um und schreibn in die target.php folgenden iFrame:
<iframe src="subtarget.php" id="advert"></iframe>
Bei am "normalen" Nutzer soit jetzt da AdBlocker die Ressource blockiern, während bei am Bot da iFrame glodn und die IP-Adresse in die Datenbank gschriebn wird. Statt die id "advert" zu setzn, kinnan mia die subtarget.php a einfach advertisting.php nennen - damit soit Adblock scho aktiv wern.