In meiner Lösung gibt es für humane Besucher nun nur noch die normalen Textfelder, Spambots sehen (bisher) einen "Honigtopf" mehr. Dieser ist per CSS-Style "visibility:hidden" ausgeblendet. Mit Hilfe der PHP basierten Formularprüfung lässt sich nun das Absenden des Spam wirksam verhindern.
Damit ich das selber auch einmal wiederfinde, hier Schritt für Schritt:
- PHP Datei erstellen und hochladen in Verzeichnis /template/inc_script/frontend_init, Rechte 644. Dateiname spielt keine Rolle, z.B. ValidateFormSubmission.php, mit Inhalt:
Code: Select all
<?php /********************************************************************************************/ /** * Testet auf diverse Formulareingaben, hier angepasst auf das Abfangen von Spam mit einem Honigtopf-Feld */ /********************************************************************************************/ // ------------------------------------------------------------------------------------------- // obligate check for phpwcms constants if (!defined('PHPWCMS_ROOT')) {die("You Cannot Access This Script Directly, Have a Nice Day."); } // ------------------------------------------------------------------------------------------- function Stop_SpamValidateFormSubmission( &$postvar, &$form, &$mail ) { //debug_print_backtrace(); // Sicherheitsrisiko wenn vergessen wird diese Zeilen nach Ende der Arbeiten zu entfernen. //echo '<br />===== postvar ===========================<br />'; //dumpVar($postvar); //echo '<br />===== $POST ===========================<br />'; //dumpVar($_POST); // echo '<br />===== form ==============================<br />'; // dumpvar($form); //echo '<br />===== mail ==============================<br />'; // ist für die meisten anwendungen uninteressant: //dumpvar($mail); //echo '<br />===== mail ende =========================<br />'; foreach ($_POST as $key => $value) { // Spam bots like to post web adresses. Error everywhere if a field data contains http, except the allowed refferer field named "kommt_von_seite" if (strpos($key, " " ) !== false) // empty data is OK continue; if (strpos($key, "kommt_von_seite") !== false) // this field is allowed to contain http in its data continue; if (strpos($value, "http") !== false) { // this field data contains the text http - this is probably a bot // echo ("<pre>Value = $value, Key = $key</pre>\r\n"); die ("<br />We are sorry but your data could not be processed. Please call if you find this should not have happened. Error: ". __LINE__ /*." @". __FILE__ */); } } if (isset($_POST["hnypot"]) && $_POST["hnypot"] !== "your spam here") { // the bot has filled out every text element in our form, even the hidden honeypot field. die ("<br />We are sorry but your data could not be processed. Please call if you find this should not have happened. Error: ". __LINE__ /*." @". __FILE__*/); } } ?>
- Inhalt der Datei s. unten.
- Im CP Formular wird ein neues Feld eingefügt:
- Typ = Text (mehrzeilig)
- Name = hnypot
- Label = (bleibt leer)
- M/R = 3 (nicht so wichtig, ein bisschen Platz für Spam )
- Wert = your spam here
- Fehlertext = (bleibt leer)
- CSS Klasse = (bleibt leer)
- CSS Stil = visibility:hidden
- Weiter unten, unterhalb der Empfänger-Vorlage
- PHP-Funktion = Stop_SpamValidateFormSubmission
- Formular kann gesichert werden
- Zum Ausprobieren den CSS-Stil vom "Honigtopf"-Feld entfernen, der dadurch sichtbar wird. Wird dessen Wert nicht geändert, wird das Formular versendet, steht dort etwas anderes als "your spam here" erhält man einen Serverfehler
Anmerkungen:
- Die meisten Bots senden über das Kontaktformular Text mit URLs. Enthält ein Textfeld den String "http" führt dies hier ebenfalls zu einer Fehlermeldung. Das mag nicht in jedem Anwendungsfall erwünscht sein.
- In meinen Formularen setze ich regelmäßig ein Hidden Feld für den Referrer, das heißt bei mir "kommt_von_seite" und kann natürlich "http" enthalten. Daher wird dieses Feld gar nicht weiter geprüft.
- Die Funktion greift auf die $_POST Daten zurück und nicht auf den Eingangsparameter $postvar. Dieser ist nur gesetzt (und dann nahezu identisch zu $_POST), wenn im Formularkopf unter Datenbank "Formularergebnis speichern" gesetzt wurde. Gepeichert wird allerdings bevor die Prüfunktion aufgerufen wird und so landen dann auch alle Spam-Anfragen in der Datenbank.
- Leider ist die Prüffunktion kein Rückgabewert vorgesehen. Wenn die Prüfung durchfällt ist ein die(...)-Befehl die einzige Option, das Backend vom Versenden der Mail abzuhalten. Sieht hässlich aus, aber nur für den Bot, und der ist selbst hässlich