robertternes: Kontakt-Formular mit Spam-und Kontrollschutz

Hallo!

Ersteinmal vielen Dank für eure damalige Hifle beim Script. Hier nochmal die Erklärung für alle:
Ich habe ein Formular in HTML, dass die eingegebenen Daten beim Absenden an die mailer.php schickt, um diese dort auswerten zu lassen. Unten habe ich nochmal den kompletten Code.
Mein Problem ist, dass ich durch dieses Formular "vollgespammt" werden kann. Das kann darin liegen, dass wen jemand so fies ist und eine Minute lang die Enter Taste drückt, dass die Nachricht dann hunderte Mal abgeschickt wird.
Ich möchte euch nun fragen bzw. bitten mein Script soweit zu verbessern, dass es

  • EMail Adresse kontrolliert (ein @ Zeichen und mind. ein Punkt)
  • Kontrollieren des Textinhaltest auf (B)CC-Header (ausschließen)
  • IP Sperre, damit jemand nur jede halbe Stunde eine Mail schicken kann
  • Sperre, dass das Formular nur einmal abgesandt werden kann (und nicht ständig auf Enter klicken oder die Dankseite aktualisieren)

Ich hoffe, dass das mir jemand ins Script einbauen kann, da ich PHP noch nicht so gut kann.

SCRIPT der mailer.php:
---------------------------------------------------------------------
<html>
<head>
<title>Kontakt-Formular</title>
</head>
<body>

<?php
echo $abschicken;
if($abschicken == "Absenden")
{
   if(empty($name) || empty($email) || empty($nachricht) || empty($adresse))
   {
      echo "Es wurden nicht alle Felder ordnungsgemäß ausgefüllt. Bitte kehren Sie zurück und vervollständigen Sie Ihre Angaben!";
   }
   else
   {
      while(list($feld,$wert)=each($HTTP_POST_VARS))
      {
         if($feld!="abschicken")
         {
            $mailnachricht.=ucfirst($feld).": $wert\n";
         }
      }
      $mailnachricht.="\nDatum/Zeit: ";
      $mailnachricht.=date("d.m.Y H:i:s");
      $mailbetreff="Kontakt: ";
      $mailbetreff.=$HTTP_POST_VARS[betreff];
      mail("webdesign@pharao-software.de", $mailbetreff, $mailnachricht, "From: $email");
      echo "Vielen Dank für Ihre Anfrage!";
   }
}
else
{
   echo "Ein Fehler ist aufgetreten.";
}

?>

</body>
</html>
---------------------------------------------------------------------

Ich hoffe Ihr könnt mir helfen! Schonmal vielen vielen Dank!
MfG
Robert Ternes

  1. Hallo Robert,

    Ersteinmal vielen Dank für eure damalige Hifle beim Script.

    *argh* ich meinte natürlich, dass du im _gleichen_ Thread (->[pref:t=73227&m=421562]) nochmal nachfragen sollst ...

    Das kann darin liegen, dass wen jemand so fies ist und eine Minute lang die Enter Taste drückt, dass die Nachricht dann hunderte Mal abgeschickt wird.

    och, das geht noch viel fieser :-) (nein, ich verrate nicht, wie)

    • EMail Adresse kontrolliert (ein @ Zeichen und mind. ein Punkt)

    das dürfte sich mit einem regulären Ausdruck lösen lassen: /^(.+?)@(.+?).(.+?)$/ (ungetestet) und das dann in preg_match (->http://de3.php.net/preg_match) einsetzen

    • Kontrollieren des Textinhaltest auf (B)CC-Header (ausschließen)

    du musst nur das was du an den 4.Parameter der Funktion mail übergibst daraufhin überprüfen - am sinnvollsten prüfst du ob wirklich nur eine E-Mailadresse in dem String vorkommt, also wirklich nur ein @ (such dir eine passende Stringfunktion auf http://de2.php.net/ref.strings dafür aus :-))

    • IP Sperre, damit jemand nur jede halbe Stunde eine Mail schicken kann

    dafür müsstest du die IP-Adresse nach dem Versenden der Mail z.B. in einer Textdatei zusammen mit dem Zeitpunkt speichern, und immer vor dem Versenden der Mail prüfen, ob ein Eintrag in der Datei vorhanden ist und wenn ja, wie alt der schon ist. Das Problem an der Methode ist nur, dass die Zuordnung IP - User nicht eindeutig sein muss - AOL verwendet afaik Proxies, so dass mehrere User die selbe IP haben können.

    • Sperre, dass das Formular nur einmal abgesandt werden kann (und nicht ständig auf Enter klicken oder die Dankseite aktualisieren)

    dafür könntest du bei jedem Aufruf des Formulars eine ID generieren, die als hidden-Feld mit an die Datei mailer.php geschickt wird - diese Datei prüft dann ob mit dieser ID schonmal eine Mail verschickt wurde, und wenn nein, wird die Mail verschickt und die ID gespeichert (so ähnlich funktioniert das hier im Forum übrigends auch).

    Ich hoffe, dass das mir jemand ins Script einbauen kann, da ich PHP noch nicht so gut kann.

    nein, wir sind hier bei _self_html und nicht bei _get_html - wenn du Hilfe brauchst, den Code selbst zu schreiben, bekommst du auch aber fertige Scripte gibt es nicht.

    if($abschicken == "Absenden")

    warum ignorierst du eigentlich das Array $_POST?

    Grüße aus Nürnberg
    Tobias

    --
    Selfcode: sh:( fo:) ch:? rl:( br:< n4:& ie:% mo:| va:) de:] zu:) fl:( ss:| ls:[ js:|
    1. Hallo!

      Das dürfte sich mit einem regulären Ausdruck lösen lassen: /^(.+?)@(.+?).(.+?)$/ (ungetestet) und das dann in preg_match einsetzen.

      Ähmm... wie soll ich das in mein Script reinbringen?

      du musst nur das was du an den 4.Parameter der Funktion mail übergibst daraufhin überprüfen - am sinnvollsten prüfst du ob wirklich nur eine E-Mailadresse in dem String vorkommt, also wirklich nur ein @

      Und wie soll das gehen? Ich blicke da nicht durch.

      dafür müsstest du die IP-Adresse nach dem Versenden der Mail z.B. in einer Textdatei zusammen mit dem Zeitpunkt speichern, und immer vor dem Versenden der Mail prüfen, ob ein Eintrag in der Datei vorhanden ist und wenn ja, wie alt der schon ist. Das Problem an der Methode ist nur, dass die Zuordnung IP - User nicht eindeutig sein muss - AOL verwendet afaik Proxies, so dass mehrere User die selbe IP haben können.

      Dann lassen wir die IP Sperre weg, aber die Idee mit der ID nummer ist gut:

      dafür könntest du bei jedem Aufruf des Formulars eine ID generieren, die als hidden-Feld mit an die Datei mailer.php geschickt wird - diese Datei prüft dann ob mit dieser ID schonmal eine Mail verschickt wurde, und wenn nein, wird die Mail verschickt und die ID gespeichert (so ähnlich funktioniert das hier im Forum übrigends auch).

      Könntest du mir bitte ein Beispielcode zeigen, wo sowas gemacht wird?

      Wie gesagt habe ich null Ahnung wie das gehen soll. Wäre nicht doch jemand so nett mir den code umzuschreiben? Ich blick da null durch. oder wenigstens Schritt für Schritt erklären - sonst bekomm ich das einfach nicht hin. Schonmal Danke!

      1. Hallo Robert,

        Das dürfte sich mit einem regulären Ausdruck lösen lassen: /^(.+?)@(.+?).(.+?)$/ (ungetestet) und das dann in preg_match einsetzen.
        Ähmm... wie soll ich das in mein Script reinbringen?

        hast du dir http://de.php.net/preg_match mal angeschaut? - das steht nämlich, wie man preg_match anwendet (ja, ich weiß die Seite ist Englisch).

        du musst nur das was du an den 4.Parameter der Funktion mail übergibst daraufhin überprüfen - am sinnvollsten prüfst du ob wirklich nur eine E-Mailadresse in dem String vorkommt, also wirklich nur ein @
        Und wie soll das gehen? Ich blicke da nicht durch.

        *seufz* warum schaust du nicht einfach mal auf die Seite die ich angegeben habe, und suchst dir eine Funktion aus? "Ermittelt, wie oft eine Zeichenkette in einem String vorkommt" hört sich doch schon mal nicht schlecht an, oder? somit wäre die Funkion substr_count() doch ganz nett (->http://de2.php.net/substr_count).

        dafür könntest du bei jedem Aufruf des Formulars eine ID generieren, die als hidden-Feld mit an die Datei mailer.php geschickt wird - diese Datei prüft dann ob mit dieser ID schonmal eine Mail verschickt wurde, und wenn nein, wird die Mail verschickt und die ID gespeichert (so ähnlich funktioniert das hier im Forum übrigends auch).
        Könntest du mir bitte ein Beispielcode zeigen, wo sowas gemacht wird?

        Wo liegt denn das Problem?

        Eine ID bekommst du, indem du einen String mit den erlaubten Zeichen anlegst, dann eine Zufallszahl ermittelst, die zwischen 0 und der Stringlänge-1 liegt und dann das nte Zeichen im String zugreifst, wobei n die Zufallszahl ist
         function idgenerieren($laenge=8){
           $zeichen = "abcdefghijklmnopqrstuvwxyz1234567890";
           $id = '';
           for($i=1;$i<=$laenge;$i++){
             $nr = mt_rand(0,strlen($zeichen)-1);
             $id .= $zeichen{$nr};
           }
           return $id;
         }

        diese ID setzt du dann in das Formular mit ein:
        echo '<input type="hidden" name="formid" value="'.idgenerieren().'">';
        (dafür muss die Datei die das Formular enthält natürlich auch eine php-Datei sein)

        die Seite die die E-Mail verschicken soll, muss dann prüfen, ob mit was dann in $_POST['formid'] drinsteht schon mal erfolgreich eine E-Mail verschickt wurde. Dazu speicherst du die IDs am einfachsten ein einer Text-Datei (durch z.B. Kommata getrennt) (ich hoffe, du weißt wie man Dateien öffnet, ausliest/beschreibt und schließt - wenn nicht, schau dir http://de.php.net/ref.filesystem mal an, besonders die Funktionen fopen, fread/fwrite, fclose und file_get_contents). Zum Prüfen, ob eine ID schon mal verwendet wurde, liest du die Datei aus, trennst den String mit explode an den Kommata und schaust mit in_array() ob die ID in dem Array steht - wenn dem so ist, wird die E-Mail nicht verschickt und eine Meldung ausgegeben. Wenn die ID aber nicht dabei ist, speicherst du die ID in der Datei (Tipp: Datei mit 'a' als 2.Parameter für fopen öffnen) und verschickst die E-Mail. Du darfst natürlich nicht vergessen, die IDs auch mal wieder zu löschen, da sonst irgendwann eine ID fälschlicherweise schon als benutzt abgelehnt wird (ggf. einen Timestamp mitspeichern, oder immer nur eine bestimmte Anzahl von IDs gleichzeitig speichern).

        Als Code könnte das ganze etwa so aussehen (nein, das funktioniert nicht, außer du hast die Funktionen datei_lesen und datei_schreiben[1] :-)):

        $idausformular = $_POST['formid'];
        $vorhandeneids = datei_lesen('ids.txt');
        $idarray = explode(',',$vorhandeneids);
        if(in_array($idausformular,$idarray)){
          //id schon vorhanden, fehlermeldung ausgeben
        }
        else{
          datei_schreiben('ids.txt',','.$_POST['formid'],'a','');
          mail(...);
        }

        Eine ganz andere Möglichkeit wäre natürlich noch http://www.dclp-faq.de/q/q-formular-mehrfach.html :-)

        Grüße aus Nürnberg
        Tobias

        [1] http://www.to-kl.de/codeschnipsel/php/funktionen/datei_schreiben.html könnte helfen (bitte nicht für die schlechte Dokumentation schlagen und ja, ich weiß wenn eine Datei die im include-path liegt angegeben wird, funktioniert die Funktion auch nicht)

        --
        Selfcode: sh:( fo:) ch:? rl:( br:< n4:& ie:% mo:| va:) de:] zu:) fl:( ss:| ls:[ js:|