Frage zu sicherer Behandlung von User Input
Thomas
- php
Hallo,
Ich fühle mich ein wenig erschlagen, von den vielen Möglichkeiten, User Input sicher zu machen.
Da gibt es mysqli_real_escape_string()
, zur Entschärfung böser Zeichen für eine SQL Query, da gibt es FILTER_SANITIZE_SPECIAL_CHARS
, was sich um '"<>&
und alles unter ASCII 32 zu kümmern scheint, htmlspecialchars()
, was wiederum FILTER_SANITIZE_FULL_SPECIAL_CHARS
entspricht (...richtig?) und sowieso sind Prepared Statements
eine gute Idee um DROP TABLE
Injection etc. zu vermeiden; - da steht die Frage im Raum, ob FILTER_SANITIZE_EMAIL
nicht noch zusätzlich durch FILTER_SANITIZE_FULL_SPECIAL_CHARS
zu jagen wäre etc. etc. etc.
Kurzum - ich sehe ein bisschen den Wald vor lauter Bäumen nicht.
…wäre da ECHT dankbar, wenn da jemand einen Leitfaden kennen würde, in erster Linie mal für Procedural (aber auch gerne im Kontrast zu OOP).
Ich meine, da muss es doch Best Practices für sicheres Auffangen und Datenbankspeicherung von User Input (sei es jetzt Username, E-Mail, etc.) geben...?! Spreche hier mal nicht von Passwort Hashing und Salting, fürchte, das würde wohl etwas zu weit führen…
Danke, Thomas
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:
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
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
Kurzum - ich sehe ein bisschen den Wald vor lauter Bäumen nicht.
Ganz einfach vergiss den Wald.
Jeder der Filter hat seinen Einsatzzweck. Die Einsatzwecke (→ Datenbank, → Mailadresse, → Ausgabe ins HTML, → Übergabe an Programme als Parameter( escapeshellarg() hast Du vergessen) , ... ) sind die Bäume.
Und jeder Bäume hat eine andere Allergie.
Dedlfix war so nett und hat das schön beschrieben:
https://wiki.selfhtml.org/wiki/Programmiertechnik/Kontextwechsel/erkennen_und_behandeln
Hallo, danke!, genau das suchte ich - (glaube ich, muss mich noch durcharbeiten, die Woche bisher wenig Zeit 😜) - einen Leitfaden, der die Hintergründe ein wenig beleuchtet.
LG Thomas