gibt es eine bestimmte System, wie man mit POST- und GET-Variablen umgeht, je nachdem, was man damit vorhat?
Grundsätzlich vom Schlimmsten ausgehen.
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.
PHP ist ein Sammelsurium aus verschiedenen Quellen, einiges überschneidet sich daher; addslashes() und mysql_[real_]escape_string() sind zum Bleistift sehr verwandt.
htmlentities() hat eine abgespeckte Variante names htmlspecialchars(), sie verarbeitet nur <, > und &, also die wirklich sicherheitsrelevanten Zeichen. htmlentities() verwurstet darüber hinaus aus mehr oder weniger kosmetischen Gründen noch Zeichen jenseits Nummer 127. Die Funktion muss dazu aber wissen, welcher Zeichensatz angewendet werden soll, und diese Angabe wiederum lässt sich andernorts auch besser einbauen, zum Beispiel mit <meta http-equiv="Content-Type" content="text/html; charset=[was-auch-immer]">.
- htmlentities, wenn ich die Daten in HTML-ausgeben will
- mysql_real_escape_string, wenn ich die Daten in MySQL eintragen will
Grundsätzlich richtig.
- POST-Variable (Einfacher Text ggf. mit Sonderzeichen) in MySQL-Datenbank eintragen (mysql_real_escape_string($variable))
Richtig.
- Abfrage aus Datenbank wo Feldwert der POST-Variable entspricht (mysql_real_escape_string($variable))
Richtig. Das ist die gleiche Situation wie bei 1), du nimmst von draußen kommende Daten und baust sie in einen SQL-Befehl ein.
- Ausgabe der POST-Variable als Überschrift in HTML (htmlentities($variable))
Richtig, wobei ich wie oben schon angedeutet htmlspecialchars() vorziehen würde.
- 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>
Falsch.
<a href="http://eineurl/<?php echo htmlspecialchars($variable) ?>">Link</a>
Du hast htmlspecialchars() vergessen. Würde der Angreifer als Dateiname "></a><a href="http://boese.bu.ben/boeser/virus.html wählen (einschließlich des führenden Anführungszeichens), hätte er schon Code eingeschmuggelt und du hättest fürdahin eine Virenschleuder in deiner Empfehlungsliste:
<a href="http://eineurl/verzeichnis/"></a><a href="http://boese.bu.ben/boeser/virus.html">Link</a>
Das Aufteilen in Verzeichnis und Datei bringt darüber hinaus keinen Sicherheitsvorteil.
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)
Prüfe immer, ob der Wert deinen Vorstellungen entspricht, nicht umgekehrt, d.h. ob er deinen Vorstellungen widerspricht. Prüfe also in diesem Fall nicht, ob die unerwünschte Zeichenkette ../ drinsteckt, sondern ob der Wert einem erwünschten Pfad entspricht, zum Beispiel mittels preg_match('|^([a-z0-9_-]+/)*[a-z0-9_-]+.[a-z]+$|i', $variable);.
Bei einer Negativprüfung läufst du Gefahr, dass der Angreifer eine andere Lücke ausnutzt, die du nicht überprüfst. Diese Gefahr ist bei einer Positivprüfung zwar nicht ausgeschlossen, aber wesentlich geringer.