Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Bezpieczeństwo uploadowanych plików
Forum PHP.pl > Forum > PHP
xwolf
Witam,

Mam taki problem odnośnie bezpieczeństwa plików: Zalogowane osoby mogą uploadować pliki na mój serwer. Można ustawić opcję, że aby obejrzeć plik potrzebne jest podanie hasła. Przez określony czas do pliku ma dostęp tylko osoba, która wrzuciła ten plik na serwer. Po upływie tego czasu dostęp do pliku mają wszyscy użytkownicy sieci. Jeśli plik jest chroniony hasłem, trzeba podać to hasło żeby zobaczyć plik.

Jakie rozwiązanie tego problemu jest najlepsze ?

Narazie mam taki pomysł, że po wrzuceniu pliku na serwer zmieniam jego nazwę na losowy ciąg 32 znaków i umieszczam w katalogu dostępnym publicznie. Wydaje mi się, że dopóki ktoś nie zna nazwy pliku ( ciężko odgadnąć ten ciąg znaków ) nie będzie mógł go otworzyć. Oczywiście osoba, która wrzuciła ten plik na serwer, po zalogowaniu, ma udostępniony link do tego pliku. Po upływie określonego czasu każdemu wyświetla się link do tego pliku. No chyba, że plik jest zabezpieczony hasłem, wtedy najpierw trzeba podać to hasło.
okitoki
hmmm, nie lepiej dać do katalogu do którego nie można wejść z sieci? nazwę i tak dobrze losować, by nikt nie nadpisał pliku, a dostęp do pliku bym zrobił przez php coś w stylu

Kod
if($jestdostep)
    readfile("/pliki/{$nazwazasobu}");
  else
    header("Location: /brakdostepu.php");


dobrze by było poleceniem header ustalić jeszcze nazwę pliku, jak jeszcze zakombinujesz obsługą mod_rewrite to nikt nie będzie wiedział ze za tym jeszcze stoi skrypt php
Pilsener
Cytat
Narazie mam taki pomysł, że po wrzuceniu pliku na serwer zmieniam jego nazwę na losowy ciąg 32 znaków i umieszczam w katalogu dostępnym publicznie
- kiepski pomysł, w dodatku skomplikowany. Nie ma sensu wynajdywać koła na nowo:

1. Tworzysz folder na te pliki i blokujesz do niego dostęp przez http (najprościej to zrobić chyba przy pomocy htaccess)
2. Wrzucasz pliki do tego folderu nazywając je 1,2,3 itd. aż do nieskończoności
3. Wszystko zapisujesz w bazie: id pliku, oryginalną nazwę pliku, nazwę nadaną przez użytkownika, typ, rozszerzenie, czas dodania, kto dodał itp.
4. Gdy ktoś chce plik pobrać, to sprawdzasz te wzystkie uprawnienia i jeśli jest ok, to pobierasz i wysyłasz do użytkownika razem z odpowiednim headerem, nazwą itp.
Quider
Cytat(Pilsener @ 27.04.2009, 14:50:18 ) *
4. Gdy ktoś chce plik pobrać, to sprawdzasz te wzystkie uprawnienia i jeśli jest ok, to pobierasz i wysyłasz do użytkownika razem z odpowiednim headerem, nazwą itp.


Mam prośbę: mógłbyś zaimplementować? Mówię poważnie smile.gif Bo ja myślałem, że nie da się zmienić nazwy pliku w locie.
pyro
Cytat(Quider @ 27.04.2009, 14:58:41 ) *
Mam prośbę: mógłbyś zaimplementować? Mówię poważnie smile.gif Bo ja myślałem, że nie da się zmienić nazwy pliku w locie.


Czytałem tylko jeden czy dwa posty z tematu ale pewnie chodzi o to:

  1. <?php
  2. header('Content-type: image/png');
  3. // tutaj dajesz kolejne headery z wielkością pliku, nazwą itd.
  4. readfile('obrazki/obrazek.png');
  5. ?>
Quider
Tak tak, to rozumiem, chodzi mi o to, że na przykład zapisuje plik w folderze pod nazwa zahaszowaną w md5, ale chce go przesłać pod nazwą np. z bazy danych.
pyro
Cytat(Quider @ 27.04.2009, 15:19:35 ) *
Tak tak, to rozumiem, chodzi mi o to, że na przykład zapisuje plik w folderze pod nazwa zahaszowaną w md5, ale chce go przesłać pod nazwą np. z bazy danych.


pobierasz nazwę z bazy danych, hashujesz md5 i patrzysz czy są pasujące pliki do tego hasha...
Quider
ale jak to przesłać w nagłówkach?
marcio
Chodzi ci o:
  1. <?php
  2. header('Content-Disposition: attachment; filename=' . $nazwa_pliku);
  3. ?>

questionmark.gif
Pilsener
I pamiętaj, że różne przeglądarki mogą wymagać różnych nagłówków oraz by pliczor nie wysyłać do przeglądarki w całości, lecz porcjami lub nawet po jednej linijce. Poszukaj na forum, download plików był omawiany wielokrotnie, ja np. realizuję to takim kodem:

  1. <?php
  2. header("Content-Type: $mime");
  3.   header("Expires: ".gmdate('D, d M Y H:i:s')." GMT");
  4.   header("Content-Disposition: attachment; filename = $nazwa");      //Dla IE:
  5.   header("Cache-Control: must-revalidate, post-check = 0, pre-check = 0");
  6.   header("Pragma: public");
  7.   header("Content-Disposition: attachment; filename = $nazwa");      // Dla reszty:
  8.   header("Pragma: no-cache");
  9.   header("Content-Length:".$wielkosc);
  10.   $file = fopen($czyi, "r");
  11.   while(!feof($file)){
  12.      print fread($file,$down_rate);
  13.   }
  14.   fclose($file);
  15. ?>
- $down_rate to wielkość porcji, warto też wstawić nazwę, typ mime oraz rozmiar pliku. W ten sposób po prostu wysyłasz dowolny zlepek bajtów jako cokolwiek pod dowolną nazwą. To w interesie usera jest, by nie pobierać i otwierać co popadnie.
Quider
No ja mam taki sam skrypt. Jak ten ostatni (niemalże identyczny) Problem jednak w tym, że jeżeli na serwerze mam plik o nazwie (dowolony ciag znakow).exe a chce go wysłać do pobrania jako program.exe.
gulldarek
$nazwa moze zawierac cokolwiek, np. program.exe
Quider
aha, czyli za to jaki plik pobrac z serwera odpoiwada funkcja do "odczytywania" pliku, jesli dobrze rozumiem. Ok, szkoda, że to nie ja jestem założycielem tematu bo należy cie się "pomogł" tongue.gif

EDIT
@down

Wielkie dzieki smile.gif
gulldarek
Dziala to nastepujaco:

Wysylasz do przegladarki naglowek Content-Disposition w ktorym definiujesz nazwe pliku pod jaka maja sie sciagnac dane (np. program.exe)

Nastepnie wysylasz zawartosc pliku, ktory ma sie sciagnac, np. (dowolny ciag znakow).exe

Czyli uzywajac kodu Pilsener bedzie to mniej wiecej tak:

  1. <?php
  2.  
  3. $czyi = "(dowolny ciag znakow).exe";
  4. $nazwa = "program.exe";
  5. $wielkosc = filesize($czyi);
  6.  
  7. header("Content-Type: $mime");
  8.  header("Expires: ".gmdate('D, d M Y H:i:s')." GMT");
  9.  header("Content-Disposition: attachment; filename = $nazwa");      //Dla IE:
  10.  header("Cache-Control: must-revalidate, post-check = 0, pre-check = 0");
  11.  header("Pragma: public");
  12.  header("Content-Disposition: attachment; filename = $nazwa");      // Dla reszty:
  13.  header("Pragma: no-cache");
  14.  header("Content-Length:".$wielkosc);
  15.  $file = fopen($czyi, "r");
  16.  while(!feof($file)){
  17.     print fread($file,$down_rate);
  18.  }
  19.  fclose($file);
  20. ?>
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.