Artikel im Internet unter http://www.hidemail.de/blog/sendmail-perl-mail.shtml.
Donnerstag, 22.3.2007, 13:27:48 Uhr

Mails versenden mit Perl - Sendmail


Jeder, der Perl dazu verwendet, um Internetseiten zu betreiben bzw. Internetdienste betreibt, steht irgendwann vor dem Problem, daß er auch mal eine oder auch mehrere Emails versenden will bzw. muß.

Der meist verwendete Ansatz ist die Verwendung von sendmail. Sendmail ist ein Systemdienst von Unix bzw. Linux (das ja ein Unix-Derivat ist).
Eine Lösung könnte z.B. so aussehen:

$text="Dies ist der Text, der versendet werden soll. Natürlich ist dies nur zum Ausprobieren gedacht";

$SENDMAIL='/usr/sbin/sendmail';
open (SENDMAIL,"|$SENDMAIL -t -f -odq meine.mailadresse\@mein-server.de") || &fehler("Kann sendmail nicht öffnen");
print SENDMAIL <<EOF;
To: $sendto
Subject: $subject
From: meine.mailadresse\@mein-server.de
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: 8bit


$text
EOF

close SENDMAIL;


Auf diese Art und Weise eine Mail zu verschicken ist eigentlich Standart und wird noch oft in Scripten gefunden.
Sie birgt jedoch vielerlei Risiken:
Sie ist anfällig für Spam
Es gibt ja so Schlaumeier, die meinen, die Ganze Welt mit Viagra und so'n Gedöns beglücken zu müssen. Dazu werden millionenfach Emails versendet, in der Hoffnung, daß es ein paar Leute gibt, die dann was kaufen. Für den Versender der Mails ein gutes Geschäft, da solche Mails kein Geld kosten und automatisiert ablaufen.
Das Problem ist jedoch, daß man Server braucht, um Mails zu versenden. Und hier liegt eine Gefahr von sendmail: Unsauber programmierte Scripte können als Spamschleuder verwendet werden.
Ich hatte das Problem auch mal und hab dann in Verbindung mit meinem Hoster herausgefunden, was schief läuft.

Und zwar sah mein Script folgendermaßen aus:


use CGI;
$query=new CGI;
$sender = $query->param('sender');
$text=$query->param('text');

$SENDMAIL='/usr/sbin/sendmail';
open (SENDMAIL,"|$SENDMAIL -t -f -odq meine.mailadresse\@mein-server.de") || &fehler("Kann sendmail nicht öffnen");
print SENDMAIL <<EOF;
To: meine.mailadresse\@mein-server.de
Subject: Kontaktformular
From: $sender
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: 8bit


$text
EOF

close SENDMAIL;


Dies war ein Script für ein Kontaktformular, ein Formular also, in dem jemand einen Kommentar und seine Absender-Mailadresse eingeben konnte. Dieses Formular leitete dann eine Mail an mich weiter. Funktionierte auch wunderbar und ist auf den ersten Blick eigentlich Idiotensicher. Meint man zumindest.
Bis mein Hoster mich anrief und meinte, über das Script wurden eben Zigtausend Mails versand und ob ich nun in Viagrahandel eingestiegen bin...

So, wo lag nun das Problem? Zuerst natürlich an dem Typen der die Mails versand hatte. Aber das brachte mich ja nun auch nicht weiter. Wo lag also das Sicherheitsloch im Script?
Nochmal zur Funktion des Scriptes: Es wird der Text und der Absender als Parameter eingelesen, das ist auf den ersten Blick schon mal ein Sicherheitsrisiko. Dann wird eine Mail an MEINE Adresse versendet, die war sogar fest eingegeben, ohne Variable. Lediglich die Absenderadresse war "variabel". Aber wo hat der Absender etwas mit dem Empfänger zu tun, denn Sinn des Spams ist es ja, daß viele Leute die Mail kriegen sollen, und nicht ich in Millionenfacher Ausführung.

Also Serverlogs gewälzt, und siehe da, etwas fiel auf: Natürlich wurde das Script direkt aufgerufen, also nicht über die Kontaktseite. Aber das war eh klar. Und noch was fiel auf: Die übergebene Parameter hatte eine Form, so daß hinter 'sender' nochmal ein to: eingeführt wurde.
Wie das nun ging, zeige ich nun nicht, weil ja die bösen Buben mitlesen. Jedenfalls stellte sich heraus, daß man dem eigentlichen from: noch ein to: mit beliebig vielen Mailempfänger anhängen konnte und sendmail hat das brav mitgemacht, laut Hoster ist das sogar ein "feature" von sendmail (da fällt mir ein Spruch von früher ein: Es ist kein bug, es ist ein feature... haha ...).

Wenn man also etwas per sendmail versendet, sollte man UNBEDINGT darauf achten, daß die Parameter nicht gefakt werden können.
Also |, %00 und Zeilenumbrüche sowie alles ausfiltern, was nicht in ein to: oder from: oder subject: oder cc: oder bcc: (hab ich was vergessen?) hineingehört oder besser erkennen und per Fehler abbrechen! Denn wenn da was drin steht, was da nicht hineingehört, ist es wahrscheinlich ein Spamversuch!


Sendmail ist fehleranfällig und läuft nicht auf allen Servern
sendmail ist ein Systemdienst von Unix, meist unter /usr/sbin/sendmail zu finden. Aber eben nur meist, manchmal auch wo anders. Das heißt: Fehlermeldungen! Und zum Anderen läuft es nicht unter Windows, da Windows sendmail nicht kennt. Also blöd, wenn man grad nicht weiß, auf welcher Maschine das Script mal laufen soll... Das kann man natürlich per Software-Abfragen ausbgeln, aber nee, ist nicht der richtige Weg!


Die Verwendung von sendmail ist also relativ einfach, man sollte aber ungebingt auf eine gute Implementierung achten!

Wie man es machen könnte, sehen Sie hier

Artikel im Internet unter http://www.hidemail.de/blog/sendmail-perl-mail.shtml.