echo $begrüßung;
Wie immer beim Übertragen oder Speichern von Daten von einem Benutzer ist natürlich größte Vorsicht geboten.
Diese "Vorsicht" ist mit jeglichen Daten geboten, wann immer sie in einen anderen Kontext gebracht werden sollen. Ob beispielsweise ein " aus einer Benutzereingabe stammt oder von einer vertrauenswürdigen Quelle ist unerheblich. Es muss immer kontextgerecht notiert werden. In HTML als " und für SQL-Statements maskiert gemäß den Regeln des jeweiligen Dialekts. (Ausnahmen wie «" muss in HTML nur in Attributwerten beachtet werden», lass ich mal unbeachtet.)
Für Entwickler die schon alleine bei Textfeldeingaben aufgrund möglicher SQL-Injections Angstschweiß auf der Stirn bekommen, ist ein Dateiupload sicher ein Grund in suizidalen Gedanken zu versinken.
Solche Entwickler sollten sich mit dem Grund für die kontextgerechte Behandlung vertraut machen. SQL-Injections sind nur eine mögliche, schädliche Ausnutzung "vergessener" Behandlung. Auch harmlose Syntaxfehler können dabei auftreten.
Der Inhalt einer Datei lässt sich in der Regel weniger einfach durchsuchen als ein kleiner String. Ein "Escapen" von Dateiinhalten ist im Bezug der "Kosten / Nutzen" Rechnung ebenso fragwürdig.
Fragwürdig ist hier eigentlich nur dein Verständnis von der Materie. Nimm mal ein SQL-Statement à la
SELECT feld FROM tabelle WHERE feld="wert"
Hier werden Befehlsbestandteile mit Nutzdaten gemischt. «wert» ist in dem Fall ein Nutzdatum. Damit es von Befehlsbestandteilen (beispielsweise einem Feldnamen) unterschieden werden kann, ist es in Anführungszeichen zu setzen. Damit ist klar gekennzeichnet, wo das Nutzdatum anfängt und wo es aufhört und die Anweisung weitergeht. Bis auf den Fall, dass im Nutzdatum ein Anführungszeichen enthalten ist. Das hieße ein vorzeitiges Ende des Wertes. Als Abhilfe wird es (unter MySQL) durch einen vorangehenden Backslash maskiert. Somit erkennt es der Empfänger als Datenbestandteil an. Es ist dabei völlig unerheblich, ob die Daten nur wenige Zeichen lang sind oder den Inhalt einer Datei darstellen. Der Empfänger muss stets Klarheit über die Bedeutung der Zeichen haben.
Deine Bedenken rühren wohl daher, dass nun der Wert durch Backslashes verfälscht ist. Das ist jedoch nur für den Kontext des SQL-Statements so. Wenn dieses vom DBMS ausgewertet wird, werden die Nutzdaten daraus extrahiert und von den Transportsicherungsbackslashes befreit. Die Daten liegen nun wieder im Original vor.
Zumindest für SQL-Statements kann man sich das Procedere sparen, wenn man Prepared Statements verwendet. Hier wird im SQL-Statement nur ein Platzhalter angegeben. Die eigentlichen Nutzdaten gelangen auf anderem Weg zum DBMS. Da sie dabei nicht in einem SQL-Statement-Kontext transportiert werden, ist keine Behandlung dafür erforderlich. [1]
Dennoch haben sich ein paar bekannte Möglichkeiten etabliert dennoch ein Mindestmaß an Sicherheit gewährleisten zu können.
- Prüfen der Dateiendung der hochgelandenen Datei.
- Prüfen des Mime-Types
- Prüfen der Dateigröße und Einschränkung der Maximalgröße
Punkt 1 und 2 lassen sich vom Absender beliebig fälschen. Punkt 3 ist kaum relevant. Man kann auch ZIP-Files erstellen, die nur eine geringe Größe haben, beim Auspacken aber beliebig groß werden können. Siehe: Archivbombe
Solange du keine eigene Inhaltsanalyse machst, kannst du nicht vom schadlosen Inhalt einer Datei ausgehen. Und selbst dann kann es Fehler in anderen Systemen geben, die beim Interpretieren der Daten Probleme bereiten können.
Der einzige Schutz besteht im Prinzip nur darin, zu überprüfen, dass die Daten der jeweiligen Spezifikation entsprechen und zu hoffen, dass die weiterverarbeitenden Programmteile robust genug programmiert sind.
Ein weiterer, grundlegender Aspekt der Sicherheit eines Uploaders, ist das Fortfahren der Arbeit mit der Datei. Entweder sie wird an ihren eigentlichen Einsatzort kopiert, etwa für eine Art Web-FTP oder sie wird sonst wie weiter modifiziert. Diese Art des Datenhandlings ist meiner Ansicht nach das gefährlichste, da eine Datei mit beliebigen Inhalten von einem Anwender ausgeführt werden könnte. Hier hilft dann besten Falls der save_mode.
Inwieweit soll dich der SafeMode (safe wie sicher, nicht save wie speichern) hier schützen? Zumal er auch ab PHP6 nicht mehr vorhanden sein wird, unter anderem weil seine Nebenwirkungen mehr störten als damit Sicherheit erreicht wurde.
Weitergehend interessant ist der Bezug von einem Datei-Upload zu Datenbank-Blobs.
Hier drängt sich wieder die Frage der Gefahr durch Injections auf, wenn man den "Stream" einer Datei in der Datenbank speichert.
Siehe oben. Ein Blob ist im Prinzip nichts anderes als eine Benutzereingabe und ganz genau so zu behandeln.
Da man klassischer Weise in einer XML-Datei nicht alle Anführungszeichen escapen sollte, steht man hier vor einem Problem, da das oben stehende SQL-Statement in einerm INSERT ausgeführt werden würde(!).
Ebenfalls siehe oben. In einem SQL-Statement ist ein Stück XML kein solches mehr sondern nur noch eine Abfolge von Zeichen. Davon sind einige aufgrund des Kontextes zu maskieren. Dass diese Zeichenfolge später mal wieder als XML interpretiert werden wird ist unerheblich. Bis dahin kann sie noch beliebig viele Kontexte durchqueren und muss dabei stets gemäß des jeweiligen Kontextes notiert werden. Ein Empfänger muss die Nutzdaten wieder aus dem Kontext-Korsett befreien und arbeitet intern immer mit dem Original, bis er sie in den nächsten Kontext überführt.
[1] Wenn du dich an der Stelle nicht gefragt hast: "Für welchen Kontext müssen sie denn dann aufbereitet werden?" dann musst du deine Kontextwechsel-Erkennungsfähigkeiten noch etwas trainieren.
Sie müssen für Prepared Statements gar nicht behandelt werden, da der P.S.-Mechanismus die Daten im Original erhalten möchte und selbst für einen ordnungsgemäßen Transport sorgt.
echo "$verabschiedung $name";