Hallo Thomas,
es gibt viele Möglichkeiten, richtig. Und nicht jede Möglichkeit ist für jeden Einsatzzweck gemacht. Und nicht jede Möglichkeit ist sinnvoll.
Unser Wiki hat einen zweiteiligen Aufsatz dazu, das Thema heißt Kontextwechsel.
Die relevanten Kontextwechsel am Server sind:
- Programmdaten nach SQL-Input
- Programmdaten nach HTML-Output
Form-Input nach Programmdaten? Nö. Das ist kein Kontextwechsel. Das sind zwar potenziell böse Daten, aber solange Du sie nur in Variablen speicherst, sind sie ungefährlich. Es wäre im Gegenteil sogar falsch, Benutzereingaben mit einer HTML-Maskierung zu versehen (z.B. htmlspecialchars) und das Ergebnis in der Datenbank zu speichern.
Was man mit Benutzereingaben machen sollte, ist
- prüfen, ob sie dem gewünschten Typ entsprechen. Wenn Du eine Zahl erwartest, lass nur Zahlen zu. Wenn Du eine Telefonnummer erwartest, prüfe im möglichen Rahmen, ob das eine Tel.-Nr sein könnte. Erwartest Du eine Mailadresse, eine Postleitzahl, ein Datum - all das kann man prüfen. Erwartest Du Eingaben ohne Zeilenumbruch, lass keine Zeilenumbrüche zu. Die Validate- und Sanitize-Filter können Dir dabei helfen, sind aber längst nicht immer das Gelbe vom Ei. Ich hatte vor Jahren mal richtig Mühe, weil ich Zahleneingaben auch mit führenden Nullen akzeptieren wollte und FILTER_VALIDATE_INT darauf besteht, dass eine führende 0 eine Oktalzahl anzeigt, und deswegen "012" entweder als Fehler ansieht oder eine 10 draus macht. Ein stumpfer intval() dagegen nimmt auch "012a" entgegen und macht 12 draus. Wollte ich auch nicht.
Und die Postleitzahl ist auch ein Drama für sich, weil jedes Land eigene Regeln hat und die Postleitzahl gar keine Zahl ist. Sondern ein String, der - in Deutschland - aus 5 Ziffern besteht.
-
eventuelle "leichte Fehleingaben" säubern, z.B. Leerstellen aus PLZ rausnehmen, bei einem Geburtsdatum ein- und zweistellige Tages- und Monatsangaben zulassen, "11. September" gleich wie "11.09." behandeln - da kann man sich beliebig austoben.
-
aber keinesfalls "böse" Zeichen rauswerfen, die möglicherweise sinnvolle Eingaben sein könnten. Zeichen an sich sind nicht böse. Sie können nur bei einem Kontextwechsel böse gemacht werden.
Den Wechsel nach SQL-Input machst Du mit der von Dir genannten mysqli_real_escape_string oder der real_escape_string-Methode auf einem mysqli-Objekt. Verwendest Du PDO, heißt die Methode quote. Besser ist ein prepare, ja, aber für ein einzelnes Statement bedeutet das Overhead, weil der prepare normalerweise einen Roundtrip zum DB Server bedeutet.
Der Wechsel von SQL Output ins Programm wird wieder 1:1 gemacht.
Bei der Ausgabe an den Browser ist dann Arbeit angesagt. JEDE Zeichenkette, deren Herkunft auch nur ein bisschen dubios ist, muss mit htmlspecialchars aufbereitet werden. Texte aus einer Ressourcentabelle von Dir gehören nicht dazu - aber es stört auch nicht, die nochmal zu maskieren.
Wenn Du natürlich irgendwoher fertige HTML Fragmente bekommst (aus einer DB oder einer Funktion), dann darfst Du sie nicht maskieren. Du musst allerdings dem HTML Lieferanten vertrauen können (also zumeist Dir oder deinen Mitprogrammierern). Wenn du HTML über einen Webservice von irgendwoher beziehst, sieht die Sache dagegen anders aus. Sowas würde ich grundsätzlich nur nach reiflicher Prüfung der Vertrauenswürdigkeit tun.
Und das war's eigentlich, was PHP angeht.
Rolf
sumpsi - posui - obstruxi