dedlfix: Behandlung von Formularwerten

Beitrag lesen

echo $begrüßung;

gibt es eine bestimmte System, wie man mit POST- und GET-Variablen umgeht, je nachdem, was man damit vorhat?

Die Einträge in den EGPCS-Arrays (.../$_GET/$_POST/...) sind zunächst einmal Eingabedaten. Auch Daten aus Dateien oder anderen Quellen wären das. Mitunter müssen Eingabedaten von ihrer "Transportsicherung" befreit werden.

Unter PHP kommt das Feature Magic Quotes hinzu, dass an der falschen Stelle die Eingabedaten bereits für eine bestimmte Ausgabe vorbereitet. Sie sind damit oftmals unbrauchbar für die eigentliche Verarbeitung und müssen erst einmal bereinigt werden, wenn man nicht die Magic Quotes generell deaktivieren kann.

Hat man die Eingabedaten in ihre Rohform gebracht kann man sie nun je nach Vorhaben verarbeiten.

Meist möchte man anschließend die Daten irgendwohin ausgeben. Viele Medien haben gemeinsam, dass sie sowohl Anweisungs- als auch Datenbestandteile in gemischter Form transportieren. Und da kommt der hier im Forum leider sehr oft notwendige Lehrsatz "Ausgabewerte müssen kontextgerecht behandelt werden!" zur Anwendung. Um über die angemessene Behandlung der Daten entscheiden zu können, muss sich man zunächst über den jeweiligen Kontext informieren, und welche Regeln für Daten dafür anzuwenden sind. Der Kontext HTML verlangt, die HTML-eigenen Zeichen in einer bestimmten Schreibweise. Der Kontext SQL (je nach Datenbank verschieden) verlangt die Notation einiger Zeichen in besonderer Form. Usw. usf. Manchmal sind mehrere Kontexte auf einmal zu beachten, z.B: Daten in einer URL, die in HTML eingefügt wird.

Ich frage mich nämlich bei dem ganzen Funktionen:
addshlashes, htmlentities, mysql_real_escape_string
und was es noch so gibt, wann ich was anwende.

Für die wichtigsten Kontexte im Webumfeld stellt PHP Funktionen zur Verfügung, die die Daten gemäß den Kontextregeln behandeln. Mitunter finden sich auch Funktionen, die zu unspezifisch sind (addslashes) oder zu viel machen (htmlentities).

  • htmlentities, wenn ich die Daten in HTML-ausgeben will

htmlspecialchars() ist für den HTML-Kontext ausreichend. Die Zeichen, die htmlentities() außerdem noch behandelt, notiert man besser in einer passenden Kodierung (die man dem Ausgabemedium in geeigneter Form mitteilt).

  • mysql_real_escape_string, wenn ich die Daten in MySQL eintragen will

Ja, das heißt: immer dann, wenn man ein SQL-Statement mit Datenbestandteilen zusammenstellt. Einige DBMS kennen Prepared Statements, bei denen Anweisung und Daten getrennte Wege gehen. In dem Fall ist keine Behandlung der Daten notwendig.

Liege ich damit in etwa richtig? Gibt es irgendwo ein Tutorial, für diese Funktionen. Ich bin zwar in der Lage, die einzelnen Funktionen zu ergoogeln, aber ich habe keine Seite gefunden, wo ich etwas allgemeines zur sicheren Behandlung von POST-/GET-Variablen finde und wann ich die mit welcher Funktion behandle.

Bei jedweden Daten, die irgendwohin ausgegeben werden sollen, muss der o.g. Lehrsatz berücksichtigt werden. Das betrifft also nicht nur Werte, die per GET/POST übertragen wurden.

Da immer wieder Fragen und Scripte hier auftauchen, die dieses Thema nicht berücksichtigen, ist das Archiv voll von diesbezüglichen Informationen.

  1. Link aus POST-Variablen (z. B. bild.jpg) basteln. Etwa so:
       <a href="http://eineurl/<?php echo $variable_verzeichnis ?>/<?php echo $variable_datei ?>">Link</a>

Du hast hier den Kontext URL, der sich in zwei Teile aufteilt, wovon du aber nur einen dargestellt hast. Und diese URL kommt im Kontext HTML zu stehen. Du benötigst eine URL-gerechte Behandlung der Daten und anschließend eine HTML-gerechte Behandlung der URL.

Werden Daten im Pfad-Teil transportiert, ist rawurlencode() die passende Funktion. Für den Querystring-Teil ist es urlencode(). Und für HTML kommt dann noch htmlspecialchars() zum Einsatz.

Wie sollte ich hier die POST-Variablen behandeln, wenn ich verhindern möchte, dass z.B. auf übergeordnete Verzeichnisse zugegriffen wird (z.B. wenn Inhalt von $variable_datei = ../../verzeichnis/datei.jpg)

Das ist kein Thema der Ein- und Ausgabedatenbehandlung. Das ist eine Prüfung im Zuge der Datenverarbeitung. Wenn es dir um den HTTP-Kontext geht, dann sorgt (hoffentlich) der Webserver dafür, dass er keine Ressourcen ausliefert, die das nicht werden sollen.

Wenn du mit PHP auf Dateien zugreifen willst, deren Name sich aus Eingabedaten zusammensetzt, so gibt es nicht nur die folgende Prüfungsmöglichkeit: Löse den Dateinamensstring mit realpath() in einen absoluten Pfad auf. Prüfe dann, ob er auf ein freigegebenes Verzeichnis zeigt.

Ist meine Behandlung in 1) bis 3) ausreichend (sicher)?
Lässt sich das möglicherweise garnicht so pauschal sagen und ist von Fall zu Fall zu entscheiden?

Wenn du das Prinzip verstanden hast, kannst du dir diese Frage nun selbst beantworten. Die ...-Injection-Sicherheitslücken entstehen immer dann, wenn es gelingt, Zeichen, die eigentlich Daten sein sollen, vom Empfänger als Anweisungsteil interpretieren zu lassen.

Solange man das nicht möchte, ist eine korrekt ausgeführte kontextgerechte Behandlung der Daten sicher. (Dass dann vielleicht verunglückte Injection-Versuche als Nutzdaten auftauchen, ist ein anderes Thema.) Schwierig wird es, wenn man den Anwendern teilweise Zugeständnisse machen möchte und einige Anweisungsteile erlauben möchte. Hier muss man genauestens aufpassen, was man erlaubt und was nicht. Einfacher ist es sicher, wenn man eine andere Syntax mit eingeschränktem Funktionsumfang (z.B. BBCode) statt eines zwar gefilterten aber ansonsten umfangreichen Systems (HTML) zur Verfügung stellt. Wenn nämlich der Filter unerkannte Lücken aufweist, ...

echo "$verabschiedung $name";