2012-09-07 12 views
7

Stworzyłem (używając a script i trochę pomocy ze Sterty i trochę pomocy od znajomych, wiem bardzo niewiele na temat PHP) prostą stronę dla lokalnej publikacji non-profit, gdzie ludzie mogą przesyłać zdjęcia.Jak mogę zabezpieczyć skrypt do przesyłania obrazów PHP przed exploitami?

nie jestem wielki z bezpieczeństwem (od podstawy ignorancji, a nie celowe zaniedbanie), ale już podjęte następujące kroki, aby chronić tę stronę:

• skryptu PHP jest ustawiony tylko zaakceptować .jpg , .png i .tif pliki do przesłania;
• podfolder, w którym zapisuje treść formularza, ma uprawnienia ustawione na 700, a podfolder, który zapisuje przesłane zdjęcia, ma uprawnienia ustawione na 700;
• zgodnie z dokumentacją, mój gospodarz ma następującą konfigurację do zapewnienia, że ​​tylko pliki .php uruchomić jako .php:

<FilesMatch \.php$> 
    SetHandler php52-fcgi 
</FilesMatch> 

• Mam umieścić plik .htaccess na odpowiednich (główny i zapisane treści) foldery:

RemoveHandler .php 
RemoveHandler .inc 
RemoveHandler .pl 
RemoveHandler .cgi 
RemoveHandler .py 
RemoveHandler .fcgi 

Overnight jednak ktoś znalazł tę stronę testową i złożone, co wydaje się być idealnie łagodny wiadomość testowa i mały .jpg. Jest to prywatna strona testowa z nieintuicyjnym adresem URL, o którym wie tylko ja i około trzech innych osób; żaden z pozostałych nie wysłał tego testu.

To oczywiście mnie martwi, że jest coś dziwnego, i obawiam się, że nie wiem wystarczająco dużo o bezpieczeństwie, aby upewnić się, że ta strona jest bezpieczna.

Czy jest coś oczywistego, czego mi brakuje?

+0

nazwa pliku podana przez użytkownika (w '$ _FILES ['upload'] ['name']') nie jest godna zaufania i można ją łatwo zmienić. Nie sprawdzaj tych rozszerzeń. Sprawdź typ mime, jeśli zaznacz, czy 'getimagesize()' zwraca poprawny wynik. Jeśli to możliwe, wygeneruj własną nazwę pliku. – MarcDefiant

Odpowiedz

8

Podczas obsługi przesłanych plików należy pamiętać, że wszystkie dane, które można znaleźć w tablicy $ _FILES, mogą zostać sfałszowane. Podróżuje przez HTTP, więc na przykład łatwo jest nadać obrazowi/jpg mime plikowi wykonywalnemu.

1- Sprawdź prawdziwy mim

PHP pochodzić z jakiejś funkcji, aby sprawdzić rzeczywistą MIME pliku. W tym celu należy użyć fileinfo

$finfo = new finfo(FILEINFO_MIME, "/usr/share/misc/magic"); 
$filename = "/var/tmp/afile.jpg"; 
echo $finfo->file($filename); 

2- Sprawdzenie właściwości obrazka

Ty najwyraźniej chce przesłać tylko obraz, tak odebrany plik musi mieć szerokość i wysokość:

Używaj getImageSize(), aby uzyskać wszystkie wymagane informacje o obrazie. Jeśli zwróci false, plik prawdopodobnie nie jest obrazem i możesz go usunąć. getImageSize może również dać typ mime, ale nie wiem, czy można mu zaufać.

2.5- Ponownie przetwórz obraz

Jak sugeruje user628405, ponownego przetwarzania obrazu z GD jest prawdopodobnie bardziej bezpieczne rzecz do zrobienia.

$img = imagecreatefrompng('vulnerable.png'); 
imagepng($img, 'safe.png'); 

Oczywiście musi być dostosowany do rodzaju obrazu. Zobacz wszystkie imagecreatefrom * w dokumentacji php.

3- Prześlij folderu Oprócz tego, co zrobiono:

upewnić się, że przesyłanie folderów nie jest dostępna w internecie. Sprawdź poprawność przesłanego pliku, a następnie przenieś go do innego folderu i zmień nazwę pliku. Uniemożliwi to wykonanie złośliwego pliku przez hakera (nie może go wykonać, jeśli nie można go uzyskać za pomocą adresu URL).

Dalsze czytanie: https://www.owasp.org/index.php/Unrestricted_File_Upload

+2

Raz miałem sytuację, gdy jakiś facet przesłał do mojego pliku PNG na serwer WWW z '' Wstawionym do danych binarnych. Ten kod nie jest wykonywalny, ale jest nadal dostępny za pośrednictwem funkcji 'include()'. I niestety 'getimagesize()' zwrócił wartość inną niż false. Udało mi się to z ponownym zapisaniem wszystkich przesłanych obrazów za pomocą '$ img = imagecreatefrompng ('vulnerable.png'); imagepng ($ img, 'safe.png'); ' – CodingHamster

+0

Jestem całkiem nowy w tym wszystkim, i nie boję się wykonywania mojej pracy domowej, ale kilka pytań: po pierwsze, czy będę dodawał polecenia fileinfo i getImageSize , a także bit zmiany nazwy pliku, w części pliku "case"? – JeanSibelius

+0

Wszystkie sprawdzenia muszą zostać wykonane jak najszybciej w zmiennej '$ _FILES ['my_files'] ['tmp_name']'; Jeśli everithing idzie dobrze, możesz przenieść plik, zmienić jego nazwę i zrobić, co trzeba z nim zrobić. – grunk

0

Możesz sprawdzić typ MIME pliku, ale nie martw się tak długo, jak twój program php może wykonywać tylko pliki .php i dbasz o to, aby nie zapisywać przesłanych plików .php w swoim skrypcie, nie ujawniając żadnego wycieku bezpieczeństwa.

Ta opcja jest ważna dla plików .php, jak również innych języków skryptowych po stronie serwera zainstalowanych na serwerze.

Lepszym pomysłem jest zachowanie białego rozszerzenia, które można zapisać w systemie plików.

+1

Nie jest to bezpośrednio związane z przesyłaniem pliku, ale możesz przesłać obraz z jakimś złośliwym kodem php jako komentarzem do niego. Jeśli w witrynie występuje luka LFI, prawdopodobnie możesz dołączyć obraz i wykonać złośliwy kod. – MarcDefiant

0

Zignorowałbym typ MIME i rozszerzenie pliku przychodzącego. Te mogą być sfałszowane.

Przechowuj te pliki w katalogu, jeśli idziesz w dół tej ulicy.

Upewnij się, że katalog jest przeznaczony tylko dla obrazów (muzyki), a następnie uzyskaj skrypt, aby umieścić na nich poprawne rozszerzenie, patrząc na format plików.

Upewnij się także, że ten katalog nie może wykonać PHP (ani niczego innego).

To zapewni Ci bezpieczeństwo.

4

nie opiera się na żadnych danych z klientem, w tym typu zawartości!

Nie zapisuj przesłanych plików w katalogu głównym. Przesłane pliki powinny być dostępne tylko za pośrednictwem skryptów, dla lepszej kontroli.

Nie zapisuj przesłanych plików z ich oryginalnymi nazwami i rozszerzeniami! Przechowuj te dane w bazie danych do późniejszego pobrania.

Powiązane problemy