Ich habe eine PHP-Datei, der ich 'datei' übergebe. Also index.php?datei=test.txt In der PHP-Datei steht zur Zeit if(!empty($_GET['datei'])) { unlink('unterverzeichnis/'.$_GET['datei']); echo 'unterverzeichnis/'.$_GET['datei'].' gelöscht.'; } Das könnte man so manipulieren, daß mein gesamter Serverdatenbestand gelöscht wird. Wie kann ich bestimmen, daß nur Dateien im Verzeichnis 'unterverzeichnis' gelöscht werden können?
:
Verschoben durch User
du musst prüfen das im Dateinamen keine "/" enthalten ist. Also kein Zeichen mit dem mit den Path ändern kann.
Hallo, per Mustervergleich kannst du das Format der übergebenen Zeichenkette prüfen. Schaue dir hierzu bitte http://de3.php.net/preg_match an. Per stat (http://de3.php.net/manual/de/function.stat.php) kann man sich noch Eigenschaften der zu löschenden Datei anschauen, um ggf. nur Dateien zu löschen, dir einem bestimmten Benutzer gehören. Per file_exists (http://de3.php.net/file_exists) kann dann noch geprüft werden, ob die angeforderte Datei überhaupt existiert. Grundsätzlich würde ich keiner Benutzereingabe trauen und den vollständigen Pfad der zu löschenden Datei von Hand zusammen bauen. Gruß, Patrick-Oliver
Wenn es nur ein bestimmtest Verzeichnis betrifft: 1) dem PHP Prozess nur Schreibrechte in diesem Verzeichnis einräumen 2) Alle Pfadangaben vorher entfernen: http://php.net/manual/de/function.basename.php
1 | if(!empty($_GET['datei'])) { |
2 | $file = basename($_GET['datei']); |
3 | unlink('unterverzeichnis/'.$file); |
4 | echo 'unterverzeichnis/'.$file.' gelöscht.'; |
5 | }
|
Ich würde auch auf Leerzeichen, Backlash sowie ".." prüfen und die ausschließen.
Aufpassen, daß man die blockierten Zeichen nicht per Multibyte-Code oder ähnlichen Zeugs codieren kann, so daß sie die Kontrollen unterlaufen. Ich würd grundsätzlich alles rausschmeißen was keine Buchstaben/Ziffern sind bzw. irgendwo vermerken welche Dateien überhaupt gelöscht werden dürfen. Dann kann auch keiner mit "kill.php?datei=*.*" rumspielen.
Das sicherste ist, den Dateiname überhaupt nicht zu verwenden. Meist werde ja noch Daten in der Datenbank ablegt. Dann kann man jeder Datei eine ID geben und dann wird sie unter diesem namen gespeichert. Welcher name dann in der Datenbank steht ist egal.
Peter II schrieb: > Meist werde ja noch Daten in der Datenbank ablegt Dann sollte man sich aber gegen SQL Injection schützen ;)
Den gesamten Server wirst du wohl auf diese Weise nicht löschen können, da PHP nicht die entsprechenden Zugriffsrechte haben dürfte. Nichts desto trotz ist es natürlich sinnvoll derartige Zugriffe nicht zuzulassen. Falls du trotzdem auf derartige Weise vorgehen möchtest, empfiehlt es sich, über die Funktion realpath() (siehe http://de2.php.net/manual/de/function.realpath.php) den resultierenden Dateinamen zu ermitteln und dann zu schauen, ob sich dieser innerhalb eines bestimmten Verzeichnisses befindet. Mit realpath() umgehst du die Möglichkeit, dass man sich per Directory Traversal (../../ etc.) durchhangeln kann.
Auch eine Einschränkung der Dateiendungen wäre denkbar, wenn Du z.B. nur *.txt Dateien hast. Einfach die Dateiendung im Script hinzufügen und den Dateinammen per Regex auf erlaubte Zeichen prüfen:
1 | $Dateiname = "FEHLER"; |
2 | if ((preg_match('/^[a-zA-Z0-9-_]{0,16}$/', $_GET['datei']))) { |
3 | $Dateiname = $_GET['datei'].".txt"; |
4 | } |
5 | |
6 | if ($Dateiname != "FEHLER") { |
7 | # HIER WIE VON Läubi BESCHRIEBEN DIE DATEI LÖSCHEN |
8 | } else { |
9 | # HIER EINTRAGE, WAS PASSIERT, WENN DIE DATEI NICHT DEM FILTER ENTSPRICHT |
10 | } |
Im Beispiel dürft der Dateiname aus bis zu 16 Zeichen bestehen und alle Zeichen von a-z, A-Z, 0-9 und noch Bindestriche und Unterstriche enthalten. Sonderzeichen wie äöüß sind hier ausgenommen. Der Code ist nicht getestet, sondern nur eben hingeschrieben. Es sollte aber hervorgehen, wie es funktionieren kann. Du könntest auch noch mit Prüfsummen arbeiten, denn Du wirst ja sicher vorher irgendwo auswählen können, welche Datei gelöscht werden soll. Dann erzeugst Du einen Hash mit dem Dateinamen und einem "geheimen" Schlüssel.
1 | $Hash = md5($Dateiname."GeheimerString"); |
Dass kannst Du dann vom Script vor dem löschen prüfen. Am besten ist jedoch, so wenig Informationen wie möglich nach "draußen" zu geben. Eine Datenbank die die Dateien referenziert ist nach wie vor die beste Lösung. Dort aber auch nicht die ID direkt an das Script übergeben, sondern einen Hashwert. :)
Chris schrieb: > Ich würde auch auf Leerzeichen, Backlash sowie ".." prüfen und die > ausschließen. und ich würde dringend empfehlen sowas nur per whitelist und nicht blacklist zu machen sonst findet man immer ein Hintertürchen!
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.