Filemanager-Skript
misterunknown
- php
0 dedlfix0 misterunknown2 dedlfix
Moin,
ich hab vor einiger Zeit angefangen ein Upload-Skript in PHP zu schreiben, was sich dann mehr und mehr zu einem Dateiverwaltungstool entwickelt hat. Sehr einfach gehalten aber doch effizient.
Da es eine simple one-file-Lösung ist und bleiben soll, hatte ich bisher noch keine Funktion zum Navigieren durch Verzeichnisse implementiert. Das heißt also, das Skript hat nur im eigenen Verzeichnis operiert.
Nun habe ich aber eine eben solche Funktion geschrieben. Es funktioniert auch alles soweit, allerdings möchte ich sicherstellen, dass man nicht durch irgendeinen Hack eine Ebene höher kommt, als das Skript liegt. Liegt das Skript also beispielsweise "/var/www/html/upload", soll man nicht "/var/www/html" anzeigen lassen können, aber auch nicht "/var/html/Foo/Bar".
Zur Sicherstellung habe ich also eine Funktion geschrieben, die den Weg "abgeht" bis zum Zielordner und, sollte man eine Ebene höher als gewollt kommen, den Vorgang abbricht:
// $_SESSION["dir"] setzt sich aus dem aktuellen Verzeichnis (absoluter Pfad)
//und dem per $_GET-übergebenen relativen Pfad zusammen
// Beispiel: /var/www/html/upload/test + ../../
// ^ akt. Verz. ^ per GET übergebener Pfad
// $_SERVER["DOCUMENT_ROOT"] wäre in diesem Fall /var/www/html/upload
$levelTeststr = substr($_SESSION["dir"],strlen($_SERVER["DOCUMENT_ROOT"]));
$levelTest = explode('/',$levelTeststr);
unset($levelWasNeg);$curlevel=0;
foreach($levelTest as $via) {
if($via=="."||$via=="") $curlevel=$curlevel;
elseif($via=="..") $curlevel--;
else $curlevel++;
if($curlevel<0)$levelWasNeg=1;
}
if(isset($levelWasNeg)&&$levelWasNeg<>0)$_SESSION["dir"]=$_SERVER["DOCUMENT_ROOT"];
if(is_dir($_SESSION["dir"]))chdir($_SESSION["dir"]);
Ich wollte jetzt von euch wissen, wie SICHER ist diese Methode der Überprüfung? Sieht jemand schon auf den ersten Blick einen Hack oder eine Injection?
Grüße Marco
Hi!
ich hab vor einiger Zeit angefangen ein Upload-Skript in PHP zu schreiben, was sich dann mehr und mehr zu einem Dateiverwaltungstool entwickelt hat. Sehr einfach gehalten aber doch effizient.
Wenn ich mir deinen Code anschaue, ist er vielleicht effektiv aber nicht sehr effizient.
Da es eine simple one-file-Lösung ist und bleiben soll, hatte ich bisher noch keine Funktion zum Navigieren durch Verzeichnisse implementiert. Das heißt also, das Skript hat nur im eigenen Verzeichnis operiert.
Da könnte man open_basedir setzen und wäre alle Sorgen los. Geht natürlich nur vor dem Scriptaufruf, weil es im Script nicht mehr erlaubt ist - jedenfalls vor PHP 5.3.0.
Nun habe ich aber eine eben solche Funktion geschrieben. Es funktioniert auch alles soweit, allerdings möchte ich sicherstellen, dass man nicht durch irgendeinen Hack eine Ebene höher kommt, als das Skript liegt. Liegt das Skript also beispielsweise "/var/www/html/upload", soll man nicht "/var/www/html" anzeigen lassen können, aber auch nicht "/var/html/Foo/Bar".
Und das geht effizienter, indem man mit realpath() den vollständigen Pfad ermittelt, den der Anwender erreichen will. Von der (magischen) Konstante __FILE__ ermittelt man den dirname() oder nimmt ab PHP 5.3 gleich __DIR__. Wenn das der Anfang vom realpath()_Ergebnis ist, ist alles in Ordnung.
Ich wollte jetzt von euch wissen, wie SICHER ist diese Methode der Überprüfung? Sieht jemand schon auf den ersten Blick einen Hack oder eine Injection?
Hast du mal einige Szenarien mit absoluten (/...) und relativen (../../...) Angaben durchgespielt?
Lo!
Moin,
Wenn ich mir deinen Code anschaue, ist er vielleicht effektiv aber nicht sehr effizient.
Ich dachte das sind Synonyme?
Und das geht effizienter, indem man mit realpath() den vollständigen Pfad ermittelt, den der Anwender erreichen will. Von der (magischen) Konstante __FILE__ ermittelt man den dirname() oder nimmt ab PHP 5.3 gleich __DIR__. Wenn das der Anfang vom realpath()_Ergebnis ist, ist alles in Ordnung.
Danke vielmals ;) Genau so eine Idee habe ich gesucht ;) Ich kannte die Funktion "realpath" leider nicht...
Hast du mal einige Szenarien mit absoluten (/...) und relativen (../../...) Angaben durchgespielt?
Ja, das habe ich. Ich hab es nicht geknackt. Ich bin auch der Meinung, dass es sicher ist, aber manchmal ist man nach stundenlanger Arbeit an einem Projekt einfach "betriebsblind" geworden für eventuelle Fehler^^
Grüße Marco
Hi!
Wenn ich mir deinen Code anschaue, ist er vielleicht effektiv aber nicht sehr effizient.
Ich dachte das sind Synonyme?
Sie werden zwar gern synonym verwendet, aber es gibt einen Unterschied zwischen beiden. Kurz gesagt: effektiv ist eine Methode, die das Ziel erreicht. Der Aufwand wird dabei nicht betrachtet. Effizient ist eine Methode, wenn sie mit möglichst wenig Aufwand zum Ziel führt.
Ich bin auch der Meinung, dass es sicher ist, aber manchmal ist man nach stundenlanger Arbeit an einem Projekt einfach "betriebsblind" geworden für eventuelle Fehler^^
Dann wechsel mal den Standpunkt. Vergiss für den Augenblick, was deine Funktion/dein Script kann und denkt dir stattdessen aus, wie du als Angreifer vorgehen würdest.
Lo!