Hallo dedlfix,
das Statement foreach ($_POST['MailRecip'] as $name)
kann nur funktionieren, wenn im HTML name="MailRecip[]" mit unterschiedlichen Values notiert ist.
Wäre das anders, wäre Claus niemals bis zu dem Punkt gekommen, an dem er jetzt seine Frage stellt.
Die Problemstellung ist doch, wie man mit der Warnung umgehen sollte, die php.da da gibt.
Prinzipiell ist sie richtig. Man kann in den values eines Buttons oder eine Checkbox allen möglichen Schabernack, bis hin zu schönen Grüßen von Little Bobby Tables, eintragen und darf sie deshalb nicht blindlings in ein SQL einbauen oder wieder auf den Bildschirm schreiben.
Wenn also in den value-Attributen der Checkboxen bereits die Mailadressen stehen, die Du anschreiben willst, dann könnte es passieren, dass ein böser Mensch das HTML editiert und da Fremdadressen eintippt. Oder einfach die Mailadressen absaugt und als Spam-Target verkauft. Lösung: Möglichst keine abgreifbaren oder fälschbaren Informationen auf die Webseite bringen, sondern nur unschädliche Referenzen auf diese Informationen. Den Bezug zwischen Referenz und eigentlichem Wert stellst Du über eine Tabelle in der Session her. In diesem Fall sähe das so aus: Nicht die Mailadressen oder deren DB-ID eintragen, sondern nur eine laufende Nummer. Und in der Session speicherst Du, welche laufenden Nummern Du für Mailadressen auf der Seite hast und stellst die Mailadresse (oder die DB-ID) daraus her. Ggf. passt es in der Session nicht. Dann könntest Du auch ein hidden input verwenden (anderswo ViewState oder PageState genannt), aber DAS muss zufallsgesalzen, prüfgesummt und mit einem serverseitig gespeicherten Key verschlüsselt werden, so dass keine Known Plaintext Attacke und keine Fälschung möglich ist. Session ist einfacher, kann aber schiefgehen wenn der User mehrere Fenster zur gleichen Session öffnet.
Die Frage, die sich Claus stellt, ist aber eine andere. Was tun, wenn im Formular zwei Elemente den gleichen Name haben und sich gegenseitig überschreiben. Im Falle der Checkboxliste könnte es sogar passieren, dass es außer den Checkboxen mit name="MailRecip[]" noch ein Input-Feld mit name="MailRecip" gibt - in dem Fall würde der foreach auf die Nase fallen.
Das ist dann eigentlich keine Frage der Security, sondern der Robustheit. Die Situation kann durch fehlerhaft geschriebenes HTML entstehen. Die auf den Produktionsserver geladene Version der Seite sollte solche Programmierfehler nicht mehr enthalten, das muss im Test auffallen. Ein Fatal Error ist besonders auffällig dafür und deshalb eine gute Antwort auf die Situation.
Oder ein Script Kiddie postet seine Attacke fehlerhaft, auch in dann ist ein Fatal Error mit stumpfem HTTP 500 Abschluss des Requests die passende Antwort. Den Absturzgrund schreibt man in den Serverlog.
Man ist geneigt, technische Fehler vom User möglichst fernzuhalten. Bestimmte Dinge müssen in einer Anwendung aber einfach passen, um sie produktiv schalten zu dürfen. Dazu gehört, dass der PHP Code alle Requests aus der HTML-Seite, die er zuvor hinausgeschickt hat, technisch auch verarbeiten kann. Kann er das nicht, MUSS es deutlich und katastrophal auffallen, sowas darf sich nicht im Log verstecken. Dass man mit bestimmten Benutzereingaben nicht klarkommt ist etwas anderes. Benutzereingaben sind von Programmen als grundsätzlich falsch, unsinnig und destruktiv vorauszusetzen. Das führt dazu, dass man als Programmierer eine gewisse Grundparanoia als Geisteshaltung entwickelt und überall erstmal die potenziellen Fehler sucht. Die muss man zügeln. "Du siehst immer alles nur negativ" - ist sonst der Satz, den man zu hören bekommt.
Dass die eigentlichen Werte aus dem erwarteten Wertebereich kommen (sprich: numerisch oder ein existierender Key in die Referenztabelle in der Session), ist dann die Nachfolgeprüfung. Aber wenn ich einen Wert nur verwende, um damit einen Array-Eintrag auszulesen, reicht array_key_exists vollkommen als Validierung.
Rolf
--
sumpsi - posui - obstruxi