E-Mail Injection Attacken und wie sie verhindert werden

Doğan Uçar

Gängige Praxis in Webapplikationen ist der Versand von E-Mails, z.B. über Kontaktformulare. Meist werden die Eingaben über das Formular in Form von E-Mail-Header gesetzt oder zur Interpretation herangezogen. E-Mail-Header werden von SMTP-Servern interpretiert und für den Versand von E-Mails über das Web genutzt.

Leider werden Benutzereingaben in den allermeisten Fällen nicht oder zu wenig gefiltert bzw. validiert, bevor sie zum Versand an den E-Mail-Server bzw. -Programm gegeben werden. In diesen Fällen ist das Formular möglicherweise anfällig für E-Mail-Header-Injection (auch bekannt unter SMTP-Header-Injection oder E-Mail-Injection). Dies bedeutet, dass ein Angreifer in der Lage sein könnte zusätzliche Header zu setzen und den Mail-Server anweisen, zusätzliche (nicht gewünschte) Aktionen durchzuführen.

E-Mail-Injection ist in erster Linie nicht schwerwiegend für den Betreiber des Mail- oder Web-Servers, welcher die Anwendung mit dem Formular hostet. Allerdings kann eine E-Mail-Injection-Attacke genutzt werden um Spam- oder Phishing-Mails zu versenden, was wiederum je nach Art und Umfang ein Sicherheitsrisiko darstellen kann. Des Weiteren läuft man gegen die Gefahr, dass die Domain die zum Versand der E-Mail genutzt wurde von gängigen Services wie Gmail, Yahoo, Outlook, etc. als „Spam“ markiert wird. Somit landen alle E-Mails dieser Domain automatisch in dem Spam-Ordner oder werden gar nicht erst zugestellt. Dieser Umstand ist nur sehr schwer bis fast unmöglich wieder rückgängig zu machen.

E-Mail-Injections in der Praxis

Wir möchten E-Mail-Injections anhand eines Praxisbeispiels mit PHP zeigen. PHP kommt mit einer Built-In Funktion mail(), die folgende Signatur aufweist:

bool mail(string $to, string $subject, string $message, string $additional_headers, string $additional_parameters)

Die ersten drei Parameter sind selbsterklärend, die letzten beiden und insbesondere $additional_headers ist im Zusammenhang von E-Mail-Injections von Bedeutung. Es seie jedoch darauf hingewiesen, dass der erste Parameter $to für Spam- und/oder Phishing-Zwecke genutzt werden kann, wenn er nicht gefiltert oder validiert von dem Benutzer kontrolliert wird.

In $additional_headers können weitere Header gesetzt werden, welche dem E-Mail-Header angehängt werden. Typische Beispiele für E-Mail-Header sind z.B. From:, Reply-To: oder CC:. Will ein Angreifer beispielsweise einen CC:-Header setzen, muss einfach nach dem Doppelpunkt der Wert eingesetzt und mit einem CRLF Character (meistens \r\n, manche E-Mail-Server akzeptieren aber auch ein \n) separiert werden. Wird die Eingabe des Benutzers nicht oder zu gering geprüft, kann sie den Versand der Emails missbräuchlich verwenden. Beispielsweise können auf diesem Wege mehrere Spam-E-Mails versendet werden (indem mehrere E-Mail-Adressen zu dem To:, CC:– und/oder BCC:– Header injiziert werden) oder der Reply-To:-Header gesetzt um sensiblen Informationen zu erhalten.

Shell Injection mit PHP mail()

Eine weitere Möglichkeit, mail() missbräuchlich zu verwenden, ist der letzte Parameter $additional_parameters. Damit Mails mit PHP versendet werden können, muss mit einem externen Mail-Dienst oder einer lokalen Software kommuniziert werden. Bei letzteren kann ein sogenannter Mail Transfer Agent (MTA) zum Einsatz kommen.

Ist also letzteres der Fall und ein MTA ist im Einsatz, kommuniziert PHP mit der MTA Software und führt Shell-Befehle aus. Dabei kann $additional_parameters genutzt werden, um zusätzliche Parameter an das MTA zu übergeben. Auch wenn die Parameter escaped werden, muss hier unbedingt bedacht werden, dass ein Angreifer Programm-Flags hinzufügen und somit zusätzliche Aktionen ausführen kann.

Anfälliger Code

mail("email@example.com", "VeryLongSubject", "The Message", "", "-f" . $_GET['data'])

Der obige Code ist anfällig für Angriffe, da der letzte Parameter aus $_GET gelesen und nicht gefiltert oder validiert an mail() übergeben wird. Ein Angreifer kann zusätzliche Flags setzen und somit das Verhalten des MTA manipulieren. Beispielsweise können Konfigurationen in sendmail mit dem Parameter -O verändert oder mit -X der Pfad eines Logfiles spezifiziert werden.

Schadcode

$_GET['data'] = 'email@example.com -OQueueDirectory=/tmp -X/var/www/html/file_with_sensitive_information.php';

Wird für den oben aufgezeigten anfälligen Code das Feld data wie hier gezeigt gesetzt, passiert folgendes: PHP legt eine Shell in /var/www/html (welches in der Standard-Konfiguration das Webroot darstellt) ab. file_with_sensitive_information.php enthält sensitive Logdaten, welche mit PHP-Code verändert oder verfälscht werden können. Auf diesem Wege kann ein Angreifer mit Zugriff auf file_with_sensitive_information.php beliebigen Schadcode auf dem Webserver ausführen.

PHP mail() sicher verwenden

Allgemein gilt: es gibt keine Zauberformel die bösartigen Missbrauch von mail() unterbinden könnte. Viel eher sollte ein kritisches analysieren aller Parameter durchgeführt werden. Folgende Faustregeln gelten allgemein als guter Ansatz:

  • Parameter to: keinen direkten Input des Users akzeptieren
  • Parameter subject: relativ sicher, stellt in der Regel kein Risiko dar
  • Parameter message: relativ sicher, stellt in der Regel kein Risiko dar
  • Parameter additional_headers: alle \r, \n und \r\n characters entfernen
  • Parameter additional_parameters: keinen Input des Users akzeptieren

Falls doch einer der oben genannten Parameter Input des Users verarbeiten oder nutzen soll, empfehlen wir einen restriktiven Filter (Whitelisting) anzuwenden. Unter keinen Umständen sollten Sie lediglich auf escaping setzen, da dies auf der einen Seite auf verschiedenen Plattformen unterschiedlich implementiert ist und auf der anderen Seite gültige Parameter ein Risiko darstellen können.

Des Weiteren empfehlen wir Mails in eine Queue zu speichern um sie zeitgesteuert zu versenden. Dies ist meist aus Sicht der Performance unumgänglich, da der Versand per SMTP oder HTTP gewisse Zeit in Anspruch nimmt, welches die Benutzererfahrung negativ beeinträchtigen kann. Auf der anderen Seite können Sie auf diesem Wege nachvollziehen welche E-Mails versendet worden sind und diese notfalls unterbinden. Weiterhin empfehlen wir Ihnen einen sogenannten Rate-Limiter, der E-Mails allgemein oder spezifisch an eine bestimmte Adresse, mit bestimmten Inhalt oder eine Kombination aus allem nur in bestimmter Anzahl versendet.

Sie wollen E-Mail nicht selbst managen?

Der Aufbau, Betrieb und Wartung eines Mail-Servers ist keine triviale Sache. Hinzu kommt das oben beschriebene Thema „E-Mail-Injection“, was ein ständiges Monitoring voraussetzt.

Wir von Ucar Solutions arbeiten derzeit an einem „E-Mail-as-a-Service“ aus der Cloud, welches Ihnen das einfache und effektive Versenden von E-Mails ermöglicht. Sie können den Versand Ihrer Mails ganz einfach über eine REST-Schnittstelle steuern, Templates pflegen und Statistiken erhalten.
Dieser Service befindet sich derzeit im Aufbau, Sie können jedoch kostenfrei und unverbindlich eine exklusive Vorschau beantragen. Nutzen Sie hierfür einfach das nachfolgende Kontaktformular: