Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Bezpieczne wysyłanie obrazów na serwer
Forum PHP.pl > Forum > PHP
WebCM
Jak bezpiecznie załadować plik graficzny na serwer, aby rzeczywiście był plikiem PNG, JPG lub GIF i nie zawierał szkodliwego kodu?

getimagesize()
Wymagania: GD
Nie chroni przed: wrzuceniem kodu PHP do obrazu (wciąż wykrywa typ: image/*)

mime_content_type()
Czy funkcja zawsze poprawnie wykrywa typ MIME pliku (NIE na podstawie rozszerzenia)? Czy jest wystarczającym zabezpieczeniem? W podręczniku PHP jest napisane, że funkcja ma status "deprecated" i odsyłają do rozszerzenia Fileinfo z PECL - wątpię, żeby było dostępne na większości serwerów, szczególnie darmowych, gdyż trzeba je doinstalować.

$_FILES['type']
Tak, to naiwna metoda, gdyż typ jest wysyłany przez przeglądarkę.

Pole MAX_FILE_SIZE
Do czego właściwie przydaje się to pole? Zabezpieczenie nie chroni przed userami, którzy zwiększą wartość tego pola.

Wniosek?
Których zabezpieczeń wystarczy użyć, aby mieć pewność, że na serwer zostanie wysłany rzeczywiście plik PNG, JPG lub GIF?
bregovic
Hmm, że tak się zapytam z poza pudełka, a nawet jeśli ktoś wyśle ci kod PHP z rozszerzeniem .jpg (or anything else) to przecież i tak ten kod się nie wykona - chyba że twój serwer parsuje pliki graficzne jako PHP, lub include'ujesz pliki graficzne w twoim kodzie. Mylę się? Poza tym, AFAIK, nie ma definitywnej możliwości sprawdzenia typu pliku, poza parsowaniem tegoż.
danek
Mój pomysł (z podkreśleniem pomysł):
1.Odpalić skrypt resize-ujący (np generujący miniaturki)
2. Jeżeli wywali błąd to to nie jest poprawny imidż, a jeżeli nie, to można założyć, że to poprawny imidż.
Ew. 3. Zresizować do podobnych wymiarów i porównać rozmiar (wagę) obu danych. Jeżeli normalny obrazek to wymiary będą podobne, a jeżeli jakiś kod to po przetworzeniu będzie o wiele mniejsze (pewnie jakiś string z błędem)
pyro
sprawdzac rozszerzenie i mime pliku PRZY CZYM trzeba wylaczyc opcję HTTP PUT w serwerze (w apache'u jest ona domyslnie wylaczona), z kolei w ISS w niktorych wersjach jest wlaczona ta opcja i trzeba ją ręcznie wylaczyc
Pilsener
Sposób stary jak świat: wczytać kilka pierwszych i ostatnich bajtów z pliku by zobaczyć, co zawiera. Użyć biblioteki GD i wykonać jakąś operację na obrazku - jeśli będzie poprawna, to obrazek jest ok.
pyro
Cytat(Pilsener @ 5.11.2008, 13:35:17 ) *
Sposób stary jak świat: wczytać kilka pierwszych i ostatnich bajtów z pliku by zobaczyć, co zawiera. Użyć biblioteki GD i wykonać jakąś operację na obrazku - jeśli będzie poprawna, to obrazek jest ok.


... i właśnie przez takie myślenie dużo stron jest podatnych na ataki
bim2
@pyro
Jak już tak mówisz, to może wyjaśnić jak zrobić to dobrze smile.gif
pyro
bim2, juz napisalem, patrz wyzej.

Napewno to nie jest bezpieczne jesli zrobi sie tak jak powiedzial Pilsener
MMX3
boże dzieci się flejmują o bezpieczeństwie. Prawda jest jedna. Zabezpieczyć się można tylko przed ludźmi którzy chcą ale nie potrafią się włamać. A ci co chcą i potrafią plus mają dość determinacji napewno obejdą. A co do samego tematu to exploit na GD to dla mnie coś nowego. Pierwszy resize powie że pomimo dobrego headera pliku wewnątrz jest kaszana.
WebCM
MMX: A jeśli nie chcę zmniejszać obrazu?

Na razie sprawdzam rozszerzenie pliku oraz wywołuję getimagesize(), aby sprawdzić, czy szerokość jest większa od 0, a wymiary mniejsze od maksymalnych ustawionych w konfiguracji. Do tego move_uploaded_file().

Czy to wystarczy?
Riklaunim
Cytat(WebCM @ 6.11.2008, 15:39:05 ) *
MMX: A jeśli nie chcę zmniejszać obrazu?

Na razie sprawdzam rozszerzenie pliku oraz wywołuję getimagesize(), aby sprawdzić, czy szerokość jest większa od 0, a wymiary mniejsze od maksymalnych ustawionych w konfiguracji. Do tego move_uploaded_file().

Czy to wystarczy?


Tak winksmiley.jpg

Plus jeżeli zachowujesz oryginalną nazwę pliku to sprawdź czy nie zawiera HTML smile.gif
WebCM
Teoretycznie nazwa pliku nie może zawierać znaków: <, >, ", ?... Przynajmniej w systemie Windows. Czy jest więc zagrożenie, że nazwa pliku będzie zawierać HTML lub przełamie znacznik <img>?
pyro
Cytat(MMX3 @ 6.11.2008, 11:31:55 ) *
boże dzieci się flejmują o bezpieczeństwie. Prawda jest jedna. Zabezpieczyć się można tylko przed ludźmi którzy chcą ale nie potrafią się włamać. A ci co chcą i potrafią plus mają dość determinacji napewno obejdą. A co do samego tematu to exploit na GD to dla mnie coś nowego. Pierwszy resize powie że pomimo dobrego headera pliku wewnątrz jest kaszana.


Tak oczywiście, to wogóle nic nie zabezpieczajmy i dajmy kazdemu wejsc do systemu, gratuluje "intieligęcji" MMX3
Riklaunim
Cytat(WebCM @ 6.11.2008, 16:32:52 ) *
Teoretycznie nazwa pliku nie może zawierać znaków: <, >, ", ?... Przynajmniej w systemie Windows. Czy jest więc zagrożenie, że nazwa pliku będzie zawierać HTML lub przełamie znacznik <img>?

Pod uniksami można w nazwie pliku wpisać różne znaki winksmiley.jpg Najlepiej będzie jak będziesz generował własną nazwę z time() (unikając zarazem nadpisywania plików o tej samej nazwie).
l0ud
Prawda jest taka, że wystarczy kontrola nagłówka obrazka, zapisanie go pod właściwym rozszerzeniem - oczywiście pod warunkiem, że nie ma innych dziur, np. pozwalających na include dowolnego obrazka. Nawet jeżeli plik jpeg nie będzie poprawny, to co z tego? Nikt się przez to nie włamie...
pyro
Cytat(l0ud @ 6.11.2008, 21:46:41 ) *
Prawda jest taka, że wystarczy kontrola nagłówka obrazka, zapisanie go pod właściwym rozszerzeniem - oczywiście pod warunkiem, że nie ma innych dziur, np. pozwalających na include dowolnego obrazka. Nawet jeżeli plik jpeg nie będzie poprawny, to co z tego? Nikt się przez to nie włamie...


.. i jest to dobre rozwiązanie, jednak co, jesli ktos chce zapisac plik o nazwie jaką on miał? smile.gif wtedy patrz nad ktorys z moich postow wyzej tongue.gif
l0ud
No dokładnie, nazwa powinna być unikalna winksmiley.jpg Najlepiej na podstawie analizy nagłówka / funkcji getimagesize rozpoznać typ obrazka i na jego podstawie dodać rozszerzenie, do unikalnej, wygenerowanej nazwy pliku.
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.