Es ist im wesentlichen egal,
wie die Daten in das lokale Programm kommen - GET, POST, COOKIE
oder Request-Parameter spielt kaum eine Rolle. Es ist jedoch
wesentlich, dass diese Variablen a) keine Variablen des lokalen
Programmes unkontrolliert überschreiben können und b) dass der
Übergang von solchen benutzerkontrollierten Variablen in lokale
Variablen des Programmes nur nach einer Prüfung der Variablen
auf legale Werte stattfindet.
Das bedeutet:
-
Variablen mit vorgegebenen Werten aus einer Wertemenge
("Auswahlvariablen"), wie sie zum Beispiel aus einem <select>
fallen:
Das Programm sollte ein lokales Array haben, das die möglichen
Werte als Index eines Hash enthält:
$val = array(
"wert1" => 1,
"wert2" => 1,
"wert3" => 1
);
Die Prüfung von $_GET["selectvar"] kann nun so aussehen:
$checkedvar = isset($val[$_GET["selectvar"]]) ? $_GET["selectvar"] : "default";
Wenn $_GET["selectvar"] einen in $val definierten Wert hat, dann
wird dieser Wert nach $checkedvar übernommen. Hat man versucht,
dem Programm einen vierten Wert unterzuschieben, dann wird
$checkedvar auf "default" gesetzt.
Das Programm arbeitet dann ausschliesslich mit $checkedvar. Auf
diese Weise können dem Programm keine beliebigen Werte aus
$_GET["selectvar"] untergeschoben werden.
-
Variablen, die eine bestimmte Form haben müssen, aber für
die nicht die abgeschlossene Wertemenge aufgezählt werden
kann ("Freitextvariablen mit Formvorschrift"):
Das Programm sollte eine oder mehrere Regex in einem Feld
vorliegen haben:
$val = array(
'/^[a-zA-Z ]+$/',
'/^[0-9-]+$/'
);
Die Prüfung kann nun so aussehen:
$checkedvar = "default";
if (isset($_GET["inputvar"])) {
foreach ($val as $k => $v) {
if (preg_match($v, $_GET["inputvar"])) {
$checkedvar = $_GET["inputvar"];
break;
}
}
}
Wenn $_GET["inputvar"] einen Wert hat, der auf eines der Muster
in $val passt, wird dieser Wert in $checkedvar übernommen. Dazu
müssen die Muster in $val natürlich vorne und hinten verankert
sein (also mit ^ beginnen und $ enden), sonst kann man der
Prüfung etwas unterschmuggeln. Paßt kein Muster, hat
$checkedvar hinterher den Wert "default".
Das Programm arbeitet dann ausschliesslich mit $checkedvar. Auf
diese Weise können dem Programm keine beliebigen Werte aus
$_GET["selectvar"] untergeschoben werden.
-
Variablen, die eine numerische Form haben müssen.
Numerische Variablen können durch eine einfache Konvertierung
erzwungen werden. Danach muss eine Überpruefung des
Wertebereiches erfolgen:
$checkedvar = isset($_GET["numericvar"]) ? $_GET["numericvar"]+0 : 0;
Durch die Addition von 0 wird eine Konvertierung auf Integer
erzwungen. Der Wert ist hinterher entweder Wert des numerischen
Prefix von $_GET["numericvar"] oder 0. "123abc" wird also zu
123, "fasel" zu 0. Ein fehlender Wert wird durch das isset()
ebenfalls zu 0.
-
Variablen, die Dateinamennatur haben.
Programme sollen oft Dateinamen, aber keine Pfadnamen annehmen.
Eine Prüfung auf "/" im Dateinamen reicht oftmals als
Sicherheitsprüfung aus. Zwingt man außerdem noch die Endung
hinten dran, erschwert man die Ausnutzung von Sicherheitslücken
zusätzlich, sollten dennoch welche vorhanden sein.
$checkedvar = "default";
if (isset($_GET["filenamevar"])
&& !preg_match('=/=', $_GET["filenamevar"])) {
$checkedvar = $_GET["filenamevar"] . ".ext";
}
-
Templatenamen
Templatenamen sind kein Spezialfall von Dateinamen oder Namen
mit Formvorschrift, sondern ein Spezialfall von vorgegebenen
Werten aus einer Liste und sollten wie der erste Fall behandelt
werden. Danke.
-
Benutzerinput, der Tags enthalten kann
Cross Site Scripting Attacks sind Attacken, in denen eine
Benutzereingabe aus einem Formular in die eigene Site als HTML,
CSS oder anderer Formattext übernommen wird. Auf diese Weise
kann der Benutzer eigene Elemente in unsere Website einbinden
(etwa Bilder, Formulare oder Javascript von seiner Site), die
einem Opfer dann als legitime Bestandteile unserer Site
erscheinen und mit den Rechten unserer Site beim Opfer
ausgeführt werden.
strip_tags() auf GRUNDSÄTZLICH ALLE Benutzereingaben ist eine
ausgesprochen gute Idee. Das schließt gegebenenfalls den
Referer und andere benutzerkontrollierte Variablen mit ein! So
existiert zum Beispiel eine Attacke gegen webalizer, bei der man
einer Site Referer unterschiebt, die HTML enthalten. In der
webalizer-generierten Referer-Statistik der Site erscheint dann
feindseliges HTML!