7.10 Temporäre Dateien
Manchmal wird für ein Skript eine oder mehrere temporäre Datei(en) benötigt. Zur Erzeugung einer solchen Datei gibt es verschiedenste Verfahren.
Verzeichnis wählen
Zunächst einmal lässt sich über den Ort debattieren, an dem eine solche Datei erstellt werden soll.
Das könnte das aktuelle Arbeitsverzeichnis, /tmp oder auch jedes andere Verzeichnis sein. Es empfiehlt sich jedoch, für temporäre Dateien auch das Verzeichnis für temporäre Dateien (also /tmp) zu verwenden.
Dateinamen wählen
Es ist nicht sonderlich schlau, eine Datei wie /tmp/a und /tmp/b als temporäre Dateien zu verwenden.
Zum einen sind diese Dateien vom Namen her recht einfallslos, was zur Folge haben kann, dass auch andere Programme oder Skripte solche Dateinamen verwenden. <Solche Programme gehören im Übrigen in den Mülleimer.>
Zum anderen gibt es dadurch ein Sicherheitsproblem: Ein Angreifer könnte eine Race Condition erschaffen und ausnutzen. Sagen wir, dass Ihr Shellskript auf die folgende Weise in die Datei /tmp/a schreibt:
echo $1 > /tmp/a
Listing 7.52 Sehr verwundbarer Code
Würde der Angreifer auch nur einen Hauch von Hacking-Know-How besitzen, so würde er sofort sehen, dass dieser Code, wenn er vom Superuser ausgeführt wird, praktisch alle Türen auf einem Linux-System öffnet. Würde der Angreifer einfach vorher einen Link von /tmp/a auf /etc/passwd erzeugen, so würde der Superuser beim Aufruf des Skripts (vielleicht ohne es zu merken) die Passwortdatei überschreiben.
Wäre der Angreifer zudem in der Lage, den übergebenen Parameter $1 zu manipulieren, dann könnte er den neuen Inhalt der Passwortdatei selbst gestalten ;-) <Mehr zum Thema »Sichere Programmierung« erfahren Sie in unserem Buch »Praxisbuch Netzwerksicherheit«, 2. Auflage.>
Prozess-ID
Nun könnte man sagen, dass der einfachste Weg, Abhilfe zu schaffen, der ist, dass man an den Dateinamen einfach die Prozess-ID des Shellskripts anhängt, also etwa folgendermaßen den Skriptcode modifiziert:
echo $1 > /tmp/a.$$
Listing 7.53 Immer noch verwundbarer Code
Dies ist aber immer noch relativ unsicher, da sich Prozess-IDs unter Linux inkrementieren und daher sehr einfach voraussagen lassen. <Es sei denn, man verwendet Kernel-Patches wie GRSecurity, die randomisierte Prozess-IDs ermöglichen.>
mktemp
Eine wesentlich bessere Lösung stellt dabei das Programm mktemp dar, das beim Aufruf eine Datei im Verzeichnis
/tmp erstellt. Diese Datei hat eine recht lange und vor allen Dingen zufällige Endung, die sich nur sehr schwer voraussagen lässt. Den Dateinamen gibt mktemp dabei aus. Das obige Skript ließe sich also folgendermaßen wesentlich sicherer implementieren:
echo $1 > `mktemp`
Listing 7.54 Schon relativ sicherer Code
Das Problem besteht nun darin, dass Sie keine Ahnung haben, wie der entsprechende Dateiname heißt. Daher muss der Dateiname gemerkt (und am besten auch gleich nach der Verwendung wieder überschrieben werden).
TMPFILE=`mktemp` echo $1 > $TMPFILE ... ... # Den Dateinamen in $TMPFILE überschreiben rm -f $TMPFILE TMPFILE="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
Listing 7.55 Schon relativ sicherer Code
Jetzt müsste es dem Angreifer schon gelingen, entweder den Dateinamen vorherzusagen, oder er müsste das Programm mktemp hacken und seine Version durch die des Systems ersetzen. <Dies wiederum ließe sich mit Intrusion-Detection-Systemen für Dateisysteme herausfinden. Mehr hierzu in unseren anderen Büchern ;-)>
... Natürlich ist der Inhalt der temporären Datei noch nicht unwiderruflich gelöscht, aber auch dies soll nur erwähnt werden, weil eine Lösung des Problems das eigentliche Thema (Shellskriptprogrammierung) nicht mehr trifft.