Formular vor Bots schützen?

Hallo!

Ich verlose unter FestivalGewinn.de 2 Gewinnspielkarten. Das Gewinnspiel sollte nur für einen kleinen Kreis Musikbegeisterter sein, nun wurde es aber offenbar auf diversen Gewinnspielseiten veröffentlicht und ich erhalte pro Tag rund 12.000 Schrottanmeldungen mit Daten von Leuten, die ganz offensichtlich per Bot eingetragen wurden (Opa Müller, 64, besucht wohl kaum ein Festival …).

Das Schlimme ist, dass der Bot scheinbar jeden Variabelnwert übergeben kann. Beim Geburtsdatum z.B. muss ein Monat ausgewählt werden, dennoch erhalte ich per Mail Anmeldungen mit folgendem Datenformat: TT.MM.JJJJ

Wie kann ich Bots aussperren, also erreichen, dass tatsächlich nur die Daten abgeschickt werden können, die auch gefordert sind?

Danke für eure Hilfe!

Matthias

Hi Matthias

Dann überprüf doch die werte in PHP bevor du sie in die Datenbank einträgst.

Monat Tag und Jahr dürften alles integer werte sein und Monat und Tag 1-2 stellig wärend Jahr 4 stellig ist.

Und so kannst du jeden Wert prüfen.

Name = string kann man mit RegExp kontrollieren
Tag, Monat, Jahr nach int casten und dann entweder auf länge oder auf ein in_array prüfen.
FÜr Städte, Länder gibt es genug Listen im Internett auf die man prüfen kann.
Außerdem gibt es noch Captcha die du einbauen kannst gegen Bots.

Gruß Lamer

Hi Lamer,

die Daten gehen in keine DB, sondern per sendmail in mein eMail-Postfach. Der Bot scheint die Felder gar nicht auszufüllen, sondern einfach selbst die Formular verarbeitende PHP-Datei aufrufen/auszulösen. Kann das sein?

Wäre da ein solcher Captcha sinnvoll?

Danke schon mal!

Matthias

Hi Matthias

Ob die Daten nun in eine DB gehen oder direkt per Sendmail raus ist in dem Fall egal und kann erstmal unberücksichtigt bleiben.

Und ja das kann sein da ja im Formular in HTML die Seite genau angegeben ist. Aber genau deswegen sollst du ja die Daten die übergeben werden überprüfen.

  1. Schick die Daten aus dem HTML Formular nicht mit GET sondern mit POST

  2. Kontrolliere im PHP nur auf $_POST nicht auf $_REQUEST

  3. Kontrolliere die Daten die geschickt werden auf Vollständigkeit und Sinn.
    Sollten sie nicht vollständig sein füre einfach das Sendmail nicht aus.

Hier ein Beispiel damit es einfacher ist zu verstehen. Aus dem HTML Formular wird ein Geburtstag, Monat und Jahr übergeben und ein Name mit diesem Formularaufruf

Dann würde deine PHP folgendes überprüfen:

// der Geburtstag wird überprüft 
// 1. ob es ein Integer ist
// 2. ob die Zahl zwischen 1-31 liegt
$geburtstag = filter\_var( $\_POST['geburtstag'], FILTER\_VALIDATE\_INT, array(1,31) );

// der Geburtsmonat wird überprüft
// 1. ob es ein Integer ist
// 2. ob die Zahl zwischen 1-12 liegt
$geburtsmonat = filter\_var( $\_POST['geburtsmonat'], FILTER\_VALIDATE\_INT, array(1,12) );

// das Geburtsjahr wird überprüft
// 1. ob es ein Integer ist
// 2. ob die Zahl zwischen 1900 und 2000 liegt
$geburtsjahr = filter\_var( $\_POST['geburtsjahr'], FILTER\_VALIDATE\_INT, array(1900,2000) );

// Hier wird der Name geprüft der übergeben wurde. 
// 1. Auf Länge \> 2
// wenn die länge größer 2 ist wird der name in eine Temporäre
// Variable namens "Name" geschrieben

if ( strlen($\_POST['name'])\> 2) {
 $name\_temp = $\_POST['name'];
}

// nach dem die minlänge überprüft wurde schauen wir ob irgendwelche
// Zeichen die wir nicht wollen im Namen enthalten sind
// in dem Fall prüfen wir auf Zahlen, Buchstaben, Leerzeichen,
// Unterstrich und Bindestrich
// wenn das Match was anderes findet wird das rausgeworfen und
// nicht im Match mit festgehalten. Darum vergleichen wir danach
// noch mal das Match mit dem übergebenen namen und speichern
// dann die werte in der Variablen Name
if ( $name\_temp && preg\_match('/^[a-zA-Z][a-zA-Z0-9\_-]\*/', $name\_temp, $match) ) {
 if ( $name\_temp== $match[0] ) {
 $name = $name\_temp;
 }
}

// so nach dem wir das ganze geprüft haben können wir wenn alles
// vorhanden ist die Mail schicken
// dazu prüfen wir die einzelnen Variablen auf vorhanden sein
// Wenn filter\_var etwas findet was nicht passt gibt filter\_var
// ein false zurück. Somit haben wir schon mal alle Fehleingaben 
// bei den Ints weg.
// Und wenn der Name nicht ausgefüllt ist greift unsere strlen
// regel \> 2
// sollten andere Daten drin stehen wie sätze mit satzzeichen bekommt
// das unser PregMatch mit und die Variable name wird nie ausgefüllt
// leere Variablen werden als False interpretiert also wird auch 
// wenn dort etwas nicht stimmt die if abfrage abbrechen und das Mail
// nicht ausgeführt
if ( $geburtstag && $geburtsmonat && $geburtsjahr && $name ) {
 mail(....);
}

Wenn du noch ein Captcha einbaust dann mußt du den natürlich auch noch überprüfen ob er richtig eingegeben wurde.

Wenn du das drin hast ist es schon mal sehr schwer für einen Bot dir Daten zu schicken die du nicht willst.

Allerdings ob die Daten sinnvoll sind wirst du nie 100%ige Sicherheit habe, da auch Menschen Sinnloses Zeug eingeben können.

Hoffe hab dir geholfen.

Gruß Lamer

Ich verlose unter FestivalGewinn.de 2 Gewinnspielkarten. Das
Gewinnspiel sollte nur für einen kleinen Kreis
Musikbegeisterter sein, nun wurde es aber offenbar auf
diversen Gewinnspielseiten veröffentlicht und ich erhalte pro
Tag rund 12.000 Schrottanmeldungen mit Daten von Leuten, die
ganz offensichtlich per Bot eingetragen wurden (Opa Müller,
64, besucht wohl kaum ein Festival …).

zum 1. solltest du entspr. formulierte teilnahmebedinungen auf der seite platzieren (da kannst du dann wahrscheinlich auch gleich in rechtsfragen posten, weil bei gewinnspielen soweit ich weiss recht umfangreiche gleichberechtigungsregeln beruecksichtig werden muessen).
die sinnvollste massnahme ist wie von dir genannt ein captcha.
weiter kannst du die ip(s) des/der bots sperren.
solltest du dir das mit der emailzusendung pro teilnahme nicht antun, sondern ein csv-file schreiben.

Mit JavaScript schützen
Hast du schon mal daran gedacht, das Formular mit Javasscript zu schützen.
Ich hatte noch nie einen Bot, der das geknackt hat. Bots interpretieren kein Javascript (mir ist auf jedenfall keiner bekannt).

Hier ein paar Ideen:

  1. Das Fake Formular:

document.write("</for"+„m>“);
document.write(’<’+‚form action="Richt‘+‚igeSeite.html>"‘);

  1. Hidden Field per DOM Manipulation ändern:

    document.getElementByName(„gut_boese“).value=„gut“;
    </pre>

    Dann kannst du noch Felder per js mit Document.write einfügen.

    Wichtig ist, du beim einfügen, den Sting mindestens einmal untebrichst. Sonst erkennt der Bot diesen. Also statt ‚<form>‘ schreibst du ‚<for‘+‚m>‘.