Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Download pliku i mozliwosc obejscia zabezpieczen
Forum PHP.pl > Forum > PHP
mosky
Hej,

Mam taki oto kod, ktory odpowiedzialny jest za download pliku ktorego nazwa przekazana jest do skryptu w postaci parametru $_GET.
Pomijajac sposob w jaki jest ten plik napisany - stary kod, ktory zostal napisany dawno, dawno temu czy widzicie mozliwosc "obejscia" zabezpieczen w/w pliku.

Patrze na to i w zasadzie nie widze niczego co moznaby tutaj zrobic co spowodowaloby np. wyslanie do przegladarki dowolnego pliku z katalogu domowego strony www.

Jesli jest cos czego nie widze bede wdzieczny za sugestie.


  1. require __DIR__ . '/elements/_session.php';
  2.  
  3. if (!isset($_SESSION["userid"])) {
  4. header('HTTP/1.1 401 Unauthorized');
  5. die('You must be logged in to perform this command');
  6. }
  7.  
  8. $file = (isset($_GET['file'])) ? $_GET['file'] : '';
  9.  
  10. if (preg_match('/^.*\.\.\/.*$/i', $file)) {
  11. header('HTTP/1.0 403 Forbidden');
  12. die('Invalid filename');
  13. }
  14.  
  15. $allowed_extensions = array("CSV", "DOC", "ZIP", "PDF", "DOCX");
  16.  
  17. if ($file != '' && file_exists($file) && is_readable($file)) {
  18.  
  19. $ext = substr($file, strrpos($file, '.')+1);
  20. if(!(in_array(strtoupper($ext), $allowed_extensions))) {
  21. die("Not Allowed");
  22. }
  23.  
  24. header('Content-type: text/csv');
  25. header("Content-Disposition: attachment; filename=\"{$file}\"");
  26. readfile($file);
  27. die();
  28. }
  29.  
  30. header("HTTP/1.0 404 Not Found");
  31. echo "<h1>Error 404: File Not Found</h1>";
  32. if ($file != '') {
  33. echo "<br /><h2><em>{$file}</em></h2>";
  34. }


pzdr
nospor
Dzieki temu wyrazeniu
if (preg_match('/^.*\.\.\/.*$/i', $file)) {
można podac dowolną pelna sciezke do pliku na serwerze i jesli tylko php ma do niej dostep, do pobrac stamtd dowolny plik o rozszerzeniu ktore podales.
mosky
To ktos kiedys "zalatal" poprzez sprawdzanie rozszezenia pliku.

Dzieki nospor

nospor
Powinienes uzyc
http://pl1.php.net/manual/en/function.basename.php
i majac tylko samą nazwe pliku bez sciezki pobierac plik z katalogow, ktore sam wybierasz.
mosky
Problem z tym plikiem jest taki ze siedzi to sobie w glownym katalogu i zbiera requesty z calego systemu (nie ma tam jakiegos centralnego routera tylko skrypty w strukturze aplikacji odwoluja sie do tego pliku bezposrednio).

Pliki, ktore wysylane sa do przegladarki przez ten plik siedza w roznych miejscach w strukturze katalogow wiec w $_GET musi byc przekazywana sciezka do wczesniej wspomnianych plikow bo inaczej system nie bedzie mogl tych plikow znalezc. Nie bardzo jest mozliwosc to zmienic bo aplikacja jest duza wiec latamy jak sie da.

Rozwiazanie od d.... strony ale tak to ktos kiedys zrobil.

Pyton_000
Możesz sobie napisać jakąś metodę która wypluje tablicę z dozwolonymi katalogami do przeszukania. Jeżeli plik będzie odwoływał się do innego katalogu to die.
Jeżeli natomiast skrypt ma latać po dowolnym katalogu to jest to strzał w stopę i niestety nie za bardzo się uchronisz przed tym.

Możesz ew. w drugą stronę, zrobić spis katalogów zabronionych. Wystarczy początkowa ścieżka typu /root, /home, /tmp i zrobić dopasowanie po wcześniejszym wycięciu niebezpiecznych znaków typu ../
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.