WebCM
4.11.2008, 20:25:48
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
4.11.2008, 20:34:57
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
4.11.2008, 20:56:12
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)
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
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.
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
@pyro
Jak już tak mówisz, to może wyjaśnić jak zrobić to dobrze
bim2, juz napisalem, patrz wyzej.
Napewno to nie jest bezpieczne jesli zrobi sie tak jak powiedzial Pilsener
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
6.11.2008, 13: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?
Riklaunim
6.11.2008, 14:23:18
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

Plus jeżeli zachowujesz oryginalną nazwę pliku to sprawdź czy nie zawiera HTML
WebCM
6.11.2008, 14: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>?
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
6.11.2008, 15:41:50
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

Najlepiej będzie jak będziesz generował własną nazwę z time() (unikając zarazem nadpisywania plików o tej samej nazwie).
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...
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ł?

wtedy patrz nad ktorys z moich postow wyzej
No dokładnie, nazwa powinna być unikalna

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.