Spam durch Formulare - Ist das normal?
Maxi
Hallo liebe SELFHTML-Gemeinde!
Seit einiger Zeit habe ich eine Webseite mit einem Formular über das man mir Nachrichten zuschicken kann. Soweit ist alles normal und alles funktioniert.
Doch inzwischen bekomme ich bis zu 100 Emails pro Tag mit meinem Formular als Absender. Die Formularfelder sind immer mit mehr oder weniger sinnvollen englischen Wörtern ausgefüllt - enthalten jedoch nie Links.
Ist das normaler Spam? Ich meine ohne Link ist es ja nicht einmal Werbung und bringt somit doch niemandem etwas. Kann man sein Formular irgendwie vor diesem Spam-Mißbrauch schützen?
Danke für jede Antwort!
Mein Formular-Code in HTML:
----------------------------
<form action="mail.cgi" method="post">
<table border="0" cellspacing="0">
<tr><td>Name</td><td><input name="Name" size="30" value="" tabindex="1"></td></tr>
<tr><td>Email</td><td><input name="Email" size="30" value="" tabindex="2"></td></tr>
<tr valign="top"><td>Text</td><td><textarea name="Text" rows="5" cols="30" tabindex="3"></textarea></td></tr>
<tr><td></td><td><input type="Submit" name="OK" value="Abschicken !" tabindex="4"></td></tr>
</table></form>
Mein CGI-Code:
---------------------------------
#!/usr/bin/perl
print "Content-type:text/html\n\n";
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
@pairs = split(/&/, $buffer);
foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$FORM{$name} = $value;
}
$mailprog = '/usr/sbin/sendmail';
$recipient = 'meine@email.de';
if ($FORM{'Email'} eq "") { dienice("Bitte tragen Sie Ihre Email-Kontaktadresse ein! "); }
open (MAIL, "|$mailprog -t") or dienice("Can't access
$mailprog!\n");
print MAIL "To: $recipient\n";
print MAIL "From: Mein Formular 5.00 \n";
print MAIL "Reply-to: $FORM{'Email'} ($FORM{'Name'})\n";
print MAIL "Subject: Mein Formular\n\n";
print MAIL "EMAIL von meinem Formular \n";
print MAIL "=============================================== \n";
print MAIL "Name............................: $FORM{'Name'}\n";
print MAIL "Email Adresse.......................: $FORM{'Email'}\n";
print MAIL "Sonstiges......................: $FORM{'Text'}\n";
close(MAIL);
print <<EndHTML;
<h2>Vielen Dank!</h2>
Ihre Nachricht wurde erfolgreich übermittelt. Über diesen
Link gelangen Sie zurück auf die Startseite:<br><br>
<a href="http://www.MeineWebseite.de">Zur Startseite...</a>
</body></html>
EndHTML
sub dienice {
my($errmsg) = @_;
print "<h2>Übertragung NICHT erfolgreich!</h2>\n";
print "$errmsg<p>\n";
print "</body></html>\n";
exit;
}
hi
Ist das normaler Spam?
Ja
Ich meine ohne Link ist es ja nicht einmal Werbung und bringt somit doch niemandem etwas. Kann man sein Formular irgendwie vor diesem Spam-Mißbrauch schützen?
Das Thema taucht hier regelmäßig auf, im Archiv hättest du einiges dazu gefunden. für dich interessant dürfte dieser Artikel (sunflyer.ch) sein.
so long
Ole
(8-)>
Hallo Ole,
vielen Dank für die schnelle Hilfe. Allerdings verstehe ich die Anleitung auf der von dir genannten Seite nicht ausreichend um mein Formular anzupassen.
Beim Suchen im Internet fand ich noch eine Info bei Dr. Web unter http://www.drweb.de/webmaster/kontakt-formulare.shtml
Leider bezieht sich diese auf ein PHP-Formular.
Gibt es denn keine Lösung wie ich mein vorhandenes Script "updaten" kann, damit es Spam-sicher wird?
Hi
vielen Dank für die schnelle Hilfe. Allerdings verstehe ich die Anleitung auf der von dir genannten Seite nicht ausreichend um mein Formular anzupassen.
Lösung 2 ist das was du umsetzten solltest:
"2. Versuch: Trash-Felder hinzufügen, die für den Besucher dank CSS nicht sichtbar sind und definiert sein müssen, aber keine Inhalte enthalten dürfen.
Erfolg: 100 Prozent. Die Spammer haben jedes leere Feld gefüllt."
Das heißt im Klaartext:
so long
Ole
(8-)>
Hallo Ole,
vielen Dank für den Tipp! Ich werde dies gleich umsetzen!
Allerdings sind bei mir gar nicht immer alle Felder ausgefüllt. Manchmal sind einige Felder ausgefüllt und manchmal kommt der Spam an die Ziel-Email des Formulares ohne Formularfelder und mit einem mehr oder weniger sinnvollen Fließtext. Im Betreff steht aber immer der Text aus dem Formular.
Wie kann ich auch dies verhindern?
Hi
Wie kann ich auch dies verhindern?
Gegen normalen Spam hilft nur ein Spamfilter im Mailserver/-client.
so long
Ole
(8-)>
Hallo Ole,
normal ist der Spam nicht. Ich bekomme den nur über die Email-Adresse des Formulares und auch mit genau dem Betreff des Formulars bzw. dem Betreff des Formulares als Absender der Spam-Mail. Statt der Formularfelder ist dort aber eben ein Fließtext wie z.B. dieser:
r a livin , an herlock olmes got afther me, d go sthraight to th station an give mesilf up. d lay th goods on th desk an say argeant, put me down in th hard cage. herlock olmes has jus see a man go by
oder so was:
in expectation of the play, through hearing
Hi
vieleicht wird der Spam ja auch "nur" über deinen Formmailer gesendet, dann wäre dort eine zusätzlich Abfrage nötig, die handelt, ob die Daten auch von der richtigen Seite übergeben werden.
so long
Ole
(8-)>
Hallo Ole,
das wird es wohl sein. Lustig ist nur, dass ich das Formular an mehreren Stellen einsetze und nur über zwei Stellen kommt der Spam :(
Ich werde aber einmal diese Abfrage einbauen versuchen. Das ist hoffentlich nicht zu schwer.
Vielen Dank für die super Hilfe !!!
Liebe Grüße
Maxi
Moin!
Doch inzwischen bekomme ich bis zu 100 Emails pro Tag mit meinem Formular als Absender. Die Formularfelder sind immer mit mehr oder weniger sinnvollen englischen Wörtern ausgefüllt - enthalten jedoch nie Links.
Dein Formmailer ist für Spammer angreifbar! Du solltest ihn so, wie er ist, sofort offline nehmen und durch eine vernünftige Version ersetzen!
> $mailprog = '/usr/sbin/sendmail';
[...]
> open (MAIL, "|$mailprog -t") or dienice("Can't access $mailprog!\n");
# Diese direkte Form des Zugriffs auf das sendmail ist ungefiltert - das ist im Folgenden genau das Problem!
> print MAIL "To: $recipient\n";
> print MAIL "From: Mein Formular 5.00 \n";
# In diese zwei Prints kann man nichts von außen einschleppen, aber...
> # Wenn die Felder Email und Name vorhanden sind
> # werden diese für die Reply-to Funktion benutzt
>
> print MAIL "Reply-to: $FORM{'Email'} ($FORM{'Name'})\n";
# ...in dieses Print kann man beliebige zusätzliche Header einbringen, indem man einfach ein Newline \n im Feld mitsendet und danach dann beliebigen weiteren Text, der aktiv wird. Z.B. weitere Bcc-Header, oder direkt eine komplett andere Mail.
Du mußt ganz dringend sämtliche der Felder, die du in deinen Mailheader einbaust, validieren auf korrekte Form. Zeilenumbrüche dürfen darin NIEMALS enthalten sein. Ein Zeilenumbruch ist tödlich.
- Sven Rautenberg
Hallo Sven,
vielen Dank für deine Hilfe. Ich habe den Formmailer offline genommen. Allerdings würde ich das gerne wieder zum Laufen bringen. Reicht es wenn ich den einen Zeilenumbruch entferne? Ist es dann ausreichend validiert?
Also aus
print MAIL "Reply-to: $FORM{'Email'} ($FORM{'Name'})\n";
einfach das machen:
print MAIL "Reply-to: $FORM{'Email'} ($FORM{'Name'})";
Ich habe leider nicht viel Ahnung und bekam den Formmailer von einem Freund empfohlen.
Kennst du zufällig einen kostenlosen Formmailer, der nicht so anfällig für Spam ist oder kann man das Script von mir irgendwie anpassen?
Danke ;)
Hell-O!
Reicht es wenn ich den einen Zeilenumbruch entferne? Ist es dann ausreichend validiert?
Nein. Es geht um den Inhalt von $FORM{'Email'} und $FORM{'Name'}. Du musst sicherstellen, dass dieser keine "schädlichen" Zeichen enthält, dazu gehören u.a. Newlines ("\n"). Es ist ein Grundprinzip, dass man Daten, die von außerhalb des Scripts kommen, *nie* ungeprüft einsetzt.
Also aus
print MAIL "Reply-to: $FORM{'Email'} ($FORM{'Name'})\n";
einfach das machen:
print MAIL "Reply-to: $FORM{'Email'} ($FORM{'Name'})";
Damit produzierst du Müll, da eine Headerzeile immer mit einem Newline abgeschlossen werden muss.
Kennst du zufällig einen kostenlosen Formmailer, der nicht so anfällig für Spam ist oder kann man das Script von mir irgendwie anpassen?
Ja, indem du die Daten prüfst, bevor du sie verwendest. Perlsec enthält einiges an Beispielen, wann Daten unsauber ("tainted") und damit potenziell unsicher sind. Ich mache in diesen Fällen eine simple RegExp-Prüfung, die mir nur sagt, ob die Daten sicher sind. Über die Gültigkeit sagt sie natürlich nichts aus:
my $cgi = CGI->new();
if($cgi->param('Email') =~ /^[A-Za-zÄÖÜäöü@.-_]+$/) {
# Eingabe ist sicher, da sie nur zulässige Zeichen enthält
$reply = $cgi->param('Email');
}
else {
# Fehlerbehandlung
}
Das Prinzip ist denkbar einfach: Du überlegst dir, welche Zeichen in deinen Formularfeldern erlaubt sein sollen, schreibst diese in eine Zeichenklasse und prüfst damit die Eingabe. Ich halte diesen Ansatz für sinnvoller als nach unerlaubten Zeichen zu suchen, da es in diesem Fall wesentlich übersichtlicher und einfacher ist festzustellen, was du willst, als festzustellen, was du nicht willst. Und so machst du es mit allen Eingaben.
Siechfred
Hallo Siechfred,
vielen Dank für deine Antwort. Ich verstehe worauf du hinauswillst, weiß aber nicht genau wie ich das aktuelle Script anpassen kann.
Dass der folgende Teil in irgendeiner Art und Weise eingebaut werden muss ist klar, aber ich habe keine Ahnung wo genau :(
my $cgi = CGI->new();
if($cgi->param('Email') =~ /[1]+$/) {
# Eingabe ist sicher, da sie nur zulässige Zeichen enthält
$reply = $cgi->param('Email');
}
else {
# Fehlerbehandlung
}
Muss ich diese if-Schleife vielleicht gleich am Anfang des Scripts einsetzen? Oder muss man diese if-Schleife für jede Variable einsetzen, die vom Formular verschickt wird? Oder wird sie nur für die empfindlicheren Header-Daten eingesetzt?
Ich bin hier ziemlich planlos, da ich mich bisher fast nur mit HTML befaßt hatte und noch gar nicht mit PHP, Perl oder so etwas...
Mein Script ist in meinem 1. Posting komplett abgedruckt. Ich kann es auch gerne noch einmal abdrucken. Aber Ändern kann ich es wohl nicht so gut :(
A-Za-zÄÖÜäöü@.-_ ↩︎
Moin!
vielen Dank für deine Hilfe. Ich habe den Formmailer offline genommen. Allerdings würde ich das gerne wieder zum Laufen bringen. Reicht es wenn ich den einen Zeilenumbruch entferne? Ist es dann ausreichend validiert?
Nein.
Also aus
print MAIL "Reply-to: $FORM{'Email'} ($FORM{'Name'})\n";einfach das machen:
print MAIL "Reply-to: $FORM{'Email'} ($FORM{'Name'})";
Der von dir selbst im String enthaltene Zeilenumbruch ist wichtig für einen Korrekten Mailheader. Der MUSS drinbleiben.
Das Problem ist, dass in $FORM{'Email'} eben nicht nur Strings wie
"mailadresse@example.com"
drinstehen können, sondern auch Strings wie
"mailadresse@example.com\n
Bcc: benachrichtigungsadresse@spammer.tld\n
Subject: Eigenes Subject\n
\n
Hello, Spam-Receiver,\n
buy Viagra at very low prices..."
(Als Kennzeichnung für die Zeilenumbrüche habe ich hier auch mal \n reingeschrieben, in Wirklichkeit übermittelt der Spammer dir natürlich die richtigen Zeilenumbruchzeichen LF oder CRLF.)
Wenn dein Skript daraus also die Mail zusammenbaut, erhält dein sendmail-Programm wesentlich mehr Headerzeilen, welche den Versand beispielsweise als Bcc an fremde Mailadressen realisiert, ohne dass du das willst.
Sämtliche Felder, die in den Mailheader gehen, auf enthaltene Zeilenumbruchzeichen zu prüfen, und diese mindestens zu entfernen, alternativ auch den Mailversand zu verweigern, ist das mindeste, was du tun solltest. Bedenke, dass "\n" systemabhängig sein kann und nicht für sämtliche möglichen Zeilenumbrüche steht.
Kennst du zufällig einen kostenlosen Formmailer, der nicht so anfällig für Spam ist oder kann man das Script von mir irgendwie anpassen?
Bei SELFHTML aktuell gibts einen Formmailer.
- Sven Rautenberg