Kim: Was tun gegen Spam durch Formmailer

Hallo liebe SelfHTML-Gemeinde,

vor rund zwei Wochen fragte ich hier bereits nach Hilfe da ich über meinen Formmailer Spam erhielt. Da die Email-Adresse fest eingestellt ist, betrifft der Spam nur mich, doch bei bis zu 700 Spam-Mails pro Tag ist das wirklich nervig...

Mir wurde hier das SelfHTML Formmailerscript empfohlen, welches ich dann auch verwendete. Leider brachte dies jedoch keinerlei Verbesserung und ich erhalte nach wie vor in völlig unregelmäßigen Abständen Spam durch meinen Formmailer.

Der Spam sieht so aus, dass er zufälligen englischen Text enthält (keine Links).

Das einzige was ich am Script änderte war die Einfügung des Abenders mit $antwort = $query->param('Email');  # ---> Absender - der Rest ist unverändert (Email und Link zur Dankesseite wurden natürlich auch geändert).

Ich bin schon richtig verzweifelt und weiß nicht was ich machen soll. Kann mir jemand hier einen Tipp geben?

Hier das Perl-Script von SelfHTML welches ich momentan verwende:

#!/usr/bin/perl

-------> Individuelle Parameter des Skriptes - bitte anpassen!

--> SMTP-Programm zum Versenden der Mail:

$Sendmail_Prog = "/usr/lib/sendmail";

--> Ziel-Mailadresse, an die gesendet werden soll:

$mailto = "xxxxx@xxxxx.de";

-------> Modul für CGI-Scripts einbinden:

use CGI;

-------> Modul für CGI-Scripts zum Einlesen der Formulardaten anwenden:

$query = new CGI;
@names = $query->param;

-------> interne Daten aus den erwarteten hidden-Feldern auslesen:

$delimiter = $query->param('delimiter');  # ---> Begrenzerzeichen zwischen name und value
$returnhtml = "http://www.xxxxx.de/danke.html";    # ---> URL für Dankeseite
$subject = "Formmailer";      # ---> E-Mail-Subject
$antwort = $query->param('Email');  # ---> Absender

-------> alle Whitespace-Zeichen (Leerzeichen, Tabulator, Newline) in Leerzeichen wandeln

#             VERHINDERT sonst möglichen MISSBRAUCH des Skripts
$subject =~ s/\s/ /g;

-------> Text der E-Mail aus den Formulardaten ermitteln:

$mailtext = "";
foreach(@names) {
  $name = $_;
  @values = "";
  @values = $query->param($name);
  if($name ne "return" && $name ne "subject" && $name ne "delimiter") {
    foreach $value (@values) {
      $mailtext = $mailtext.$name;
      $mailtext = $mailtext.$delimiter;
      $mailtext = $mailtext.$value."\n";
    }
  }
}

-------> E-Mail versenden:

open(MAIL,"|$Sendmail_Prog -t") || print STDERR "Mailprogramm konnte nicht gestartet werden\n";
print MAIL "To: $mailto\n";
print MAIL "From: $antwort\n";
print MAIL "Subject: $subject\n\n";
print MAIL "$mailtext\n";
close(MAIL);

-------> Dankeseite an Browser senden:

print "Location: $returnhtml\n\n";

  1. Hallo,

    also sorry aber dieses Programm würde ich so auf keinen Fall verwenden. Die Absenderadresse wird völlig ungecheckt aus dem Formular direkt als Email Header eingesetzt. Das ist ein Scheunentor für Form Spammer. Ausserdem wäre es auch ratsam ein MIME Modul die Email zusammensetzen zu lassen, als einfach nur so quick and dirty per Kommandozeile an sendmail zu übergeben.

    Gruß,
    Cruz

    1. Hallo Cruz,

      danke für die schnelle Antwort. Leider bin ich nicht so fit und habe von Perl und PHP nur sehr bedingt Ahnung. Wie man hier etwas mit MIME machen kann weiß ich auch nicht.

      Mir geht es vor allem darum nicht jeden Tag die teilweise hunderte Spams löschen zu müssen. Die Suche bei google mit "formmailer spam" ergab leider keine sehr hilfreichen Antworten. Ich fand da nur Hinweise zu Topics in Foren, die sich seit Jahren mit dem Thema befassen aber kein Ergebnis fanden.

      Es muss doch aber eine Möglichkeit geben, dass auch Laien wie ich ein kleines Formular auf ihren Webseiten unterbringen können ohne vorher intensiv PHP, Perl oder andere Sachen gelernt zu haben?

      Oder liege ich hier völlig daneben und Laien sollten sich lieber aus dem  Internet raushalten mit ihren Webseiten?

      1. Hallo Kim,

        ich finde schon dass auch Laien ruhig Webseiten haben dürfen. :) Dafür ist das Internet schließlich da. Leider kann sich aber ein Emailformular als Problem entpuppen, das man als Laie nicht mehr in Griff bekommt. Da hilft dann nur noch das Formular wieder rauszunehmen (reicht nicht auch ein mailto link?), oder sich tief genug einzuarbeiten, dass man mit sowas klarkommt.

        Man braucht nur sehr wenig Ahnung, um mit Perl und MIME::Lite eine Email zu verschicken. Das kriegst du mit Hilfe der Dokumentation sicherlich hin. Auch ein paar einfache RegExp zur Überprüfung der Formulardaten kriegst du sicherlich hin, um den gröbsten Unfug schon mal zu verhindern. Möglicherweise findest du sogar irgendwo ein fertiges Skript, dem man nachsagt, dass er seine Sache ordentlich macht. Doch leider ist das noch kein ausreichender Schutz. Du kannst damit bestenfalls verhindern, dass dein Formular zum verschicken von Spam an ANDERE missbraucht wird. Du selbst willst ja die Emails bekommen, also kannst du kaum etwas dagegen tun, dass jemand ganz legitim das Formular 700-mal am Tag ausfüllt und abschickt.

        Kurzfristig kannst du erstmal die ordentliche Überprüfung der Formulardaten in Angriff nehmen und die URL des Formulars ändern. Meine Erfahrung zeigt, dass wenn man die URL ändert, der Spammer zeitnah das Formular neu entdeckt und Tests durchführt. Wenn dein Skript die Tests besteht, d.h. der Spammer schafft es nicht Spam an ANDERE durch dein Formular zu verschicken, dann wirst du für den Spammer uninteressant und er zieht weiter. Aber der nächste Spammer kommt schon bald und macht wieder seine Tests mit deinem Formular und bei jeden Test kriegst du die Email ab.

        Um dich selbst auch davor zu schützen brauchst du eine Serverseitige Lösung in Form von intelligenten Spam Filtern, die am besten du selbst auf die dich betreffenden Angriffsmuster einstellst. Nur so kommt man langfristig klar. Das kann übrigens auch das Perl Script selbst sein, das die Emails aus dem Formular verschickt. Wenn du damit typische Phrasen oder dirty words entdeckst, schmeisst du die Mail einfach gleich weg.

        Jedenfalls ist das Form Spam Problem eine sehr lästige Angelegenheit, die leider nur mit fundiertem Fachwissen und ständigem Beobachten in Griff zu kriegen ist. Ich wünschte man könnte diesen Nervensägen ein Kabel ins Gehirn stecken und sie auf direktem Wege mit so viel Spam volladen, dass sie ihren eigenen Namen vergessen.

        Gruß und viel Glück,
        Cruz

        Hallo Cruz,

        danke für die schnelle Antwort. Leider bin ich nicht so fit und habe von Perl und PHP nur sehr bedingt Ahnung. Wie man hier etwas mit MIME machen kann weiß ich auch nicht.

        Mir geht es vor allem darum nicht jeden Tag die teilweise hunderte Spams löschen zu müssen. Die Suche bei google mit "formmailer spam" ergab leider keine sehr hilfreichen Antworten. Ich fand da nur Hinweise zu Topics in Foren, die sich seit Jahren mit dem Thema befassen aber kein Ergebnis fanden.

        Es muss doch aber eine Möglichkeit geben, dass auch Laien wie ich ein kleines Formular auf ihren Webseiten unterbringen können ohne vorher intensiv PHP, Perl oder andere Sachen gelernt zu haben?

        Oder liege ich hier völlig daneben und Laien sollten sich lieber aus dem  Internet raushalten mit ihren Webseiten?

        1. Hallo Cruz,

          vielen Dank für die hilfreiche Antwort. Ich bin bereits dabei mich ein wenig intensiver mit PHP zu befassen, doch das dauert wohl noch etwas bis ich weit genug bin um einen Formmailer mit Spamschutz zu erstellen. Denn speziell der Spamschutz ist ja der Haken - den Formmailer selbst zu erstellen wäre ja nicht das große Problem...

          Ich bleibe auf jeden Fall am Ball und lerne fleißig weiter. Mit Perl lege ich demnächst dann auch los ;)

          Eine reine Email-Adresse reicht für meine Webseite leider nicht. Da es einige Auswahlmöglichkeiten gibt ist ein Formular zwingend nötig.

          Die Email-Adresse selbst hatte ich auch schon geändert. Da jedoch der Formmailer seine Mails an eine spezielle Email schickt, konnte ich schnell merken welcher Spam von wo kommt. Das Ärgerliche ist ja, dass irgendjemand per Bot mein Formular immer wieder ausfüllt und an mich schickt. Andere sollten nicht betroffen sein, da die Ziel-Email fest eingegeben ist. Das Problem betrifft hier also eigentlich nur mich.

          Nun ja - dann muss ich eben vorerst weiter Spam löschen oder von meinem Virenschutzprogramm löschen lassen, bis ich das Problem mit PHP oder Perl lösen kann. Dank der Info, dass MIME ein Weg zum Ziel sein könnte, werde ich gezielt in diese Richtung lernen um möglichst schnell die Spam loszuwerden.

          Danke ;)

          1. Andere sollten nicht betroffen sein, da die Ziel-Email fest eingegeben ist. Das Problem betrifft hier also eigentlich nur mich.

            Da wäre ich aber sehr vorsichtig. Der Spammer hat keine Probleme die Absenderadresse, die ungeprüft als FROM Header in die Email eingesetzt wird, so zu manupielern, dass die Email als Spam an hunderte von Empfängern verschickt wird, ohne dass du es merkst.

            Cruz

            1. Hallo Cruz,

              die Zeile, die den FROM-Absender einfügte, habe ich bereits entfernt. Kurz danach trafen leider wieder 15 neue Spam bei mir ein. Mir hat dies also leider nicht geholfen. Doch wenn so andere von Spam verschont werden ist das schon mal ein erster Schritt ;)

              Danke für die Hilfe!

              1. Hallo Kim,
                wenn dein Server PHP unterstützt kannst du auch den PHP Formmailer von SELFHTML benutzen:

                http://aktuell.de.selfhtml.org/tippstricks/php/form-mail/

                In diesem kann man mit wenig PHP-Kenntnissen eine Option mit kein Spam/Spam einbauen, die Standardmäßig auf "Spam" gestellt ist.
                Dann kann man einstellen, dass die Mail nur versendet wird, wenn die Option "kein Spam" gewählt ist.
                Dann müsste der Bot automatisch die Option wechseln, wobei ich glaube, dass er das nicht tut.
                Deine Besucher müsstest du nur darauf hinweisen, dass sie die Option "kein Spam" wählen müssen, damit du ihre Mail erhältst.
                MfG,
                Christian

                1. Hallo Christian,

                  vielen Dank für den Link zu dem Script. Ich werde dieses noch heute ausprobieren. Wäre super, wenn es den Spam abfangen würde! Dann könnte ich mehr Zeit zum Lernen von PHP und Perl aufwenden statt immer den Spamordner durchzugehen und zu schauen ob auch wirklich alles Spam ist...

                  Danke ;)

      2. Da fällt mir noch ein, du kannst dein Formular auch mit einer Captcha Lösung schützen, wenn du das deinen Besuchern zumuten kannst. Das findert effektiv, dass ein Programm dein Formular abschicken kann, es muss schon ein Mensch sein.

  2. Hi,

    $antwort = $query->param('Email');  # ---> Absender

    auf die Schnelle sehe ich hier keine Validierung, da lassen sich dann uebers "from" header einschleusen.
    Ansonsten wurde vor kurzem eine praktikable, kurzfristige Lösung gepostet, um Robots auszubremsen:
    Füge ein weiteres input-Feld hinzu und verstecke es via css. Robots werden es dennoch ausfüllen. Prüfe Vorhanden- und Leersein dieses Feldes.

    Gruesse, Joachim

    --
    Am Ende wird alles gut.
  3. ¡Hola!

    Vielleicht hilft Dir das hier: http://sunflyer.ch/2005/04/30/interessante-spammer.php. Der zweite Versuch scheint gut gegen automatisierten Spam zu helfen.

    Viele Grüße vom Længlich

    1. Hallo!

      Vielleicht hilft Dir das hier: http://sunflyer.ch/2005/04/30/interessante-spammer.php. Der zweite Versuch scheint gut gegen automatisierten Spam zu helfen.

      Ja, vermutlich bis die bots diese Methode auch "verstehen".

      Da ich auch den SELFHTML PHP-Formmailer verwende, und immer wieder Spam von den üblichen Verdächtigen bekomme, suche ich nach einer konkreten Umsetzung.
      Der HTML- und CSS-Teil ist ja unproblematisch, aber wie sieht der Test auf den (Nicht-)Inhalt des Feldes in PHP aus?

      Christians Vorschlag finde ich eher für "unbedarfte Benutzer" abschreckend ;-)

      mfg Alfie

      1. Shalom!

        Ja, vermutlich bis die bots diese Methode auch "verstehen".

        Das wird noch ziemlich lange dauern, denke ich. :-)

        Der HTML- und CSS-Teil ist ja unproblematisch, aber wie sieht der Test auf den (Nicht-)Inhalt des Feldes in PHP aus?

        Du mußt nur überprüfen, ob die Variable erstens gesetzt und zweitens ein leerer String ist, also

          
        if (isset($_GET("leeresFeld") && $_GET("leeresFeld") == "") {  
        // alles ok  
        } else {  
        // Spam  
        }  
        
        

        Wobei leeresFeld überraschenderweise der Name des leeren Feldes sein soll. ;-)
        Außerdem geht dieses Beispiel davon aus, daß Du GET benutzt - mußt Du andernfalls natürlich anpassen.

        Viele Grüße vom Længlich

        1. Hallo!

          Vielen Dank, ich werde einmal die Bastelstunde eröffnen ;-)

          mfg Alfie

        2. Hallo Længlich,

          Du mußt nur überprüfen, ob die Variable erstens gesetzt und zweitens ein leerer String ist […] Außerdem geht dieses Beispiel davon aus, daß Du GET benutzt - mußt Du andernfalls natürlich anpassen.

          Und zwar wie? Es geht hier schließlich um POST und GET, nicht um SELF. ;-)

          Grüße
           Roland

          --
          SELFHTML-Community > Visitenkarten > Orlando
          Nachwuchsförderung 2.0: »Mami, sieh mal! Ich habe mit CSS eine Tabelle nachgebaut.«
  4. <yoeto>

    Zu diesem Thema habe ich heute bei Dr.Web einen interessanten Artikel gelesen: http://www.drweb.de/webmaster/sichere-formulare-captcha.shtml. Hier geht es darum, ein "Captcha" (grauenvolles Wort!) nur per PHP zu erzeugen. Ich glaube zwar nicht, dass das dauerhaft sicher ist, aber der Schutz vor Spam gleicht ohnehin dem berühmten Wettlauf zwischen Hase und Igel. Gewinnen wirst du nicht, aber du punktest gut, wenn du dem Spammer ein hohes Maß an Rechenleistung abforderst.

    </yoeto>

    --
    <signatur />
    ie:% fl:( br:< va:| ls:~ fo:{ rl:? n4:( ss:{ de:] js:( ch:] mo:| zu:)
  5. Vielen Dank für die vielen hilfreichen Antworten. Bis ich nun ausreichend PHP und Perl für meinen ganz eigenen Formmailer kann, habe ich mir dank Euch allen folgendes Script zusammengebastelt (ein Mix aus dem Script von SelfHTML und dem Schutzmechanismus eines DrWeb.de Tutorials)

    Für alle Interessierten hier das Script, was bei meinen Tests funktionierte. Optisch muss man es natürlich noch anpassen, aber es läuft und sollte Spam abfangen können (zum Preis von etwas Tipparbeit vom Besucher und der Barrierenfreiheit...).

    Man muß nur die Email-Adresse sowie den Link zur Danke-Seite (URL) fast am Anfang des Scripts eintragen.

    <?php

    Von Rene Schmidt (rene@reneschmidt.de) fuer DrWeb.de

    class Digit {

    var $bits = array(1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384);
      var $matrix  = array();
      var $bitmasks = array(31599, 18740, 29607, 31143, 18921, 31183, 31695, 18855, 31727, 31215);

    function digit( $dig ) {
        $this->matrix[] = array(0, 0, 0); // 2^0, 2^1, 2^2 ... usw.
        $this->matrix[] = array(0, 0, 0);
        $this->matrix[] = array(0, 0, 0);
        $this->matrix[] = array(0, 0, 0);
        $this->matrix[] = array(0, 0, 0); // ..., ..., 2^14

    ((int)$dig >= 0 && (int)$dig <= 9) && $this->setMatrix( $this->bitmasks[(int)$dig] );
      }

    function setMatrix( $bitmask ) {
        $bitsset = array();

    for ($i=0; $i<count($this->bits); ++$i)
          (($bitmask & $this->bits[$i]) != 0) && $bitsset[] = $this->bits[$i];

    foreach($this->matrix AS $row=>$col)
          foreach($col AS $cellnr => $bit)
            in_array( pow(2,($row*3+$cellnr)), $bitsset) && $this->matrix[$row][$cellnr] = 1;
      }
    }

    class Number {

    var $num = 0;
      var $digits = array();

    function number( $num ) {
        $this->num = (int)$num;

    $r = "{$this->num}";
        for( $i=0; $i<strlen($r); $i++ )
          $this->digits[] = new Digit((int)$r[$i]);
      }

    function getNum() { return $this->num; }

    function printNumber() {
        for($row=0; $row<count($this->digits[0]->matrix); $row++) {
          foreach( $this->digits AS $digit ) {
            foreach($digit->matrix[$row] AS $cell)
              if($cell === 1) print("<span class="s">&nbsp;&nbsp;</span>"); else print("<span class="w">&nbsp;&nbsp;</span>");
            print("<span class="w">&nbsp;</span>");
          }
          print("<br>");
        }
      }
    }

    Konfiguration

    Bitte passen Sie die folgenden Werte an, bevor Sie das Script benutzen!

    An welche Adresse sollen die Mails gesendet werden?

    $strEmpfaenger = 'abc@meinedomain.de';

    Welche Adresse soll als Absender angegeben werden?

    (Manche Hoster lassen diese Angabe vor dem Versenden der Mail ueberschreiben)

    $strFrom       = '"Formmailer" IhrAndererName@provider.xy';

    Welchen Betreff sollen die Mails erhalten?

    $strSubject    = 'Feedback';

    Zu welcher Seite soll als "Danke-Seite" weitergeleitet werden?

    Wichtig: Sie muessen hier eine gueltige HTTP-Adresse angeben!

    $strReturnhtml = 'http://www.meinedomain/danke.shtml';

    Welche(s) Zeichen soll(en) zwischen dem Feldnamen und dem angegebenen Wert stehen?

    $strDelimiter  = ":\t";

    Ende Konfiguration

    if($_POST)
    {
     $strMailtext = "";

    while(list($strName,$value) = each($_POST))
     {
      if(is_array($value))
      {
       foreach($value as $value_array)
       {
        $strMailtext .= $strName.$strDelimiter.$value_array."\n";
       }
      }
      else
      {
       $strMailtext .= $strName.$strDelimiter.$value."\n";
      }
     }

    if(get_magic_quotes_gpc())
     {
      $strMailtext = stripslashes($strMailtext);
     }

    if($zahl != $pass)
     {
      die("Falsche Kontrollzahl. Die Mail konnte nicht versendet werden.");
     }

    mail($strEmpfaenger, $strSubject, $strMailtext, "From: ".$strFrom)
      or die("Die Mail konnte nicht versendet werden.");
     header("Location: $strReturnhtml");
     exit;
    }

    ?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de">
        <head>
            <title>Einfacher PHP-Formmailer</title>
            <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
            <style>
              .s { color: black; background-color: black; }
              .w { color: white; background-color: white; }
            </style>
        </head>
        <body>
            <h1>Beispielformular</h1>
            <form action="<?php print $_SERVER['PHP_SELF']; ?>" method="post">
                <!-- Hier die eigentlichen Formularfelder eintragen. Die folgenden sind Beispielangaben. -->
                <dl>
                    <dt>Ihr Name:</dt>
                    <dd><input type="text" name="Versender" /></dd>
                    <dt>Ihre E-Mail:</dt>
                    <dd><input type="text" name="E-Mail" /></dd>
                    <dt>Sie k&ouml;nnen:</dt>
                    <dd><input type="checkbox" name="kannwas[]" value="HTML" />HTML <input type="checkbox" name="kannwas[]" value="PHP" />PHP</dd>
                    <dt>Sie sind:</dt>
                    <dd><input type="radio" name="sexus" value="M" />Mann <input type="radio" name="sexus" value="Frau" />Frau</dd>
                    <dt>Sie m&ouml;gen:</dt>
                    <dd><select name="Browser"><option value="Opera">Opera</option><option value="Mozilla">Mozilla</option></select></dd>
                    <dt>Bemerkungen:</dt>
                    <dd><textarea name="Bemerkungen" rows="3" cols="20">Bemerkungen</textarea></dd>
                </dl>
                <!-- Ende der Beispielangaben -->

    <?php
    $n = new Number( rand(1000,9999) );
    $n->printNumber();
    printf( "<h2>Dargestellt wird die Zahl %d</h2>", $n->getNum() );
    ?>

    Bitte geben Sie die Zahl ein:
    <input type="text" name="zahl" />
    <input type="hidden" name="pass" value="<? printf( "%d", $n->getNum() ); ?>" />

    <p>
                <input type="submit" value="Senden" />
                <input type="reset" value="Zurücksetzen" />
                </p>
            </form>
        </body>
    </html>