Hi,
(http://aktuell.de.selfhtml.org/tippstricks/php/form-mail/).
- Ist dieses Script sicher gegen Missbrauch?
Nein.
Es ist zwar recht gut gebaut, aber $_POST wird nicht richtig überprüft. Es wird nur auf den _Fehler_ getestet, ob $_POST leer ist, aber nicht auf _korrekte_ Eingaben.
Das ist eine kleine aber ganz gemeine Falle, in die ich auch oft genug reingetappt bin: keine Negation als Bedingung! Also keine Sätze mit "nicht", "kein" o.ä.
In diesem speziellem Fall bedeutet es, das $_POST zwar nicht leer sein darf aber sonst alles: zu lang, zu schief, zu merkwürdig, zu pervers, kriminell, sonstwie nicht so ganz koscher, kann zu Schweinereien in empfangenden Emailprogrammen führen usw. Und nicht zuletzt, wie Du selber ganz richtig erkannt hast: man könnte damit "(D)DoSen".
Aber ich kann Patrick trotzdem keinen Vorwurf machen, das Skript ist so völlig korrekt. Einzig über einen kleinen zusätzlichen Sicherheitshinweis könnte man reden, mehr aber auch nicht. Für den Rest ist dann nur noch der Benutzer zuständig.
- Wie kann ich einen einfachen Spamschutz einbauen, so dass nicht beliebig viele Mails nacheinander losgeschickt werden?
Definiere "beliebig viele [...] hintereinander" und baue das dann ein. Will sagen: Du mußt nur wissen/bestimmen, wieviele Mails in welchem Zeitraum abgesandt werden dürfen. Dann mußt Du die versandten Mails zählen. Diese Summe und der Zeitpunkt des Standes "0" muß von jeder Instanz des Scriptes gelesen werden können. Danach prüfst Du in jeder Instanz, ob das Verhältnis Anzahl Mails zu Zeiteinheit den vorgegeben Wert immer noch unterschreitet. Ist das nicht mehr der Fall wird keine Mail versandt.
Dieses Vorgehen hat einige Haken, den einen oder anderen wirst Du auch schon selber erkannt haben, nehme ich an. Ein paar der dicksten:
-
es gibt konkurrierende Schreibzugriffe auf den, na, nenn' ich es mal Zähler. Das zu regeln ist zwar nicht unbedingt hochkomplex, aber doch alles andere als einfach. Man könnte es auch ignorieren, aber das würde zu einer recht extremen Regelkurve führen.
-
das simple Wegschmeißen zusätzlicher Mails bei Erreichen des Maximaldurchsatzes ist gnadenlos, brutal und unfair. Hilft aber sogar bei DDoS, da einige Mails trotzdem durchkommen.
-
man könnte auf die abstrusesten Ideen verfallen, das Vorgehen zu "optimieren". Die einzige Möglichkeit ist jedoch der Algorithmus zur Bestimmung, wann der Hahn zugedreht werden soll: da könnte man ein wenig aus der Meß- und Regeltechnik klauen (Eine kurze Einführung gibt's es hier http://tpmn.berlios.de/page/vorlesungen/pg/Zwischenbericht.html jedoch Vorsicht: alleine die HTML-Datei ist auch ohne Bilder schon über ein Emmchen groß!), um die Gnadenlosigkeit und Brutalität etwas zu mindern. Ich habe das selber nie probiert und wäre an den Erfahrungswerten sehr interessiert falls Du das einbauen möchtest, oder jemand, der hier mitliest es schon eingebaut hat.
-
Die einzige Rückgabe an den User im Abschaltfall ist, wenn überhaupt geantwortet wird, der HTTP-Code 503 ("Service Unavailable") mit einem "Retry-After" oder der 500 ("Internal Server Error"). Eine komplette Seite mit ausführlicher Meldung zurückzugeben würden einen (D)DoS eher noch unterstützen denn entgegenwirken. Dieses Verhalten könnte evt von einem wichtigen Kunden ... ähm ... mißverstanden werden.
Das grundsätzliche Problem ist der vollständig öffentliche Zugang und die dadurch nötige Negation: "Einige will ich nicht haben", was ja, wie oben beschrieben, nicht funktioniert. Man könnte eine Registrierung einbauen? Tja, dann hast Du mit dem Registrierungsformular genau die gleichen Probleme wenn Du keine Vorauswahl triffst, wer reindarf. Da beißt sich die Katze also leider in den eig'nen Schwanz.
Die Wahrscheinlichkeit eines Angriffes hängt aber hauptsächlich davon ab, ob Du damit Geld verdienst, Deine Firma darauf angewiesen ist. Es gibt mittlerweile einige Leute, die sich darauf spezialisiert haben und Firmen erpressen. Leider sehr erfolgreich, da fast alle Firmen zahlen. Da dies zu Anfang noch nicht der Fall war, gibt es einige Berichte über das Vorgehen: es wird dabei mittels eines sehr großen (>10.000 Knoten. Bis über 60.000 sind dabei schon gezählt worden) Zombienetzwerken (Rechner mit Remotezugriff durch den Erpresser) ein DDoS auf _alle_ zur Verfügung gestellte Dienste ausgeübt. Nicht alles gleichzeitig, sondern nadelstichweise: einmal Web, dann Mail, dann DNS, dann wwi, dann gemischt usw. Dein Formmailer istdann Dein kleinstes Problem ;-)
Die Vorraussetzung "ich mach da viel Kohle mit" ist bei Dir wahrscheinlich nicht gegeben, dann gibt es nur noch die Angreifer aus emotionalen Gründen: es mag jemand stinkig auf Dich sein bzw umgekehrt (das ist mitunter sogar schlimmer) oder irgendein Scriptkiddy hat mehr oder weniger zufällig deine Seite auf's Korn genommen, um im Chat damit angeben zu können.
Diese Varianten sind aber meist recht ungeschickt bis blöd ausgeführt und der Verursacher kann relativ einfach dingfest gemacht werden.
Für diese Zwecke reicht neben dem Test von $_POST auf korrekten Inhalt einfach die oben beschriebene Maßhaltung mit Mailanzahl/Zeit. Evt wäre es noch bequem, sich bei gehäufter Überschreitung eine Mail schicken zu lassen damit man rechtzeitig einen Blick in das Log werfen kann. Wenn das pro Block immer die gleiche IP ist (können auch eine handvoll oder zwei sein, aber eben gehäuft.) kann man die Daten mit einer entspr Notiz an den zuständigen ISP schicken. Mitunter hilft's.
so short
Christoph Zurnieden