2011-09-06 11 views
12

Opracowuję skrypt php, który zastąpi bieżący, który będzie miał dużo ekspozycji na różne rynki/kraje. Ten skrypt między innymi oferuje funkcję przesyłania zdjęć.Podejście bezpieczeństwa przesyłania obrazu w języku angielskim

Po wielu lekturach na ten temat, zastosowałem się do opisanej poniżej metody. Gorąco będę wdzięczny za uwagi na temat bezpieczeństwa.

  1. Zdjęcie jest przesyłane do prywatnego folderu 777 poza katalogiem głównym.
  2. Wykonywane jest sprawdzenie, czy na liście znajdują się białe rozszerzenia (dozwolone tylko pliki jpg, gify, png), wszystko inne jest usuwane.
  3. Stosowanie getimagesize do sprawdzania wymiarów min-max i ważności fotografii.
  4. Sprawdź dopasowanie typu MIME i rozszerzenia pliku.
  5. Zmiana rozmiaru przesłanego zdjęcia na wymiary standardowe (za pomocą imagecopyresampled).
  6. Zapisywanie utworzonych plików jako jpg.
  7. Usunięcie oryginalnego pliku.
  8. Zapisuj zdjęcia za pomocą nowej (nie losowej nazwy) np. Img51244.jpg.
  9. Przenieś nowe zdjęcia do zmiennych podkatalogów folderu publicznego (uprawnienia 777) zgodnie z nie przewidywalnym algorytmem. Tj. img10000.jpg będzie przechowywany pod adresem photos/a/f/0/img10000.jpg, a img10001.jpg będzie przechowywany pod adresem photos/0/9/3/img10001.jpg. Odbywa się to z innych powodów (wykorzystanie subdomen do przesyłania statycznych treści lub korzystanie z CDN).

Skrypt zostanie uruchomiony na dedykowanym serwerze linuksowym.

+0

nic tutaj nie wyskakuje. oprócz uprawnienia 777 do folderu - jak rozumiem, jeśli ma 777 uprawnień, nie jest prywatny. ale o ile mogę powiedzieć, że to naprawdę miałoby znaczenie, gdyby twój serwer był zagrożony (co nie wygląda na to, żebym mógł to zrobić w tym samym skrypcie) – jammypeach

+2

777 nie brzmi bezpiecznie. Możliwe powiązane z http://stackoverflow.com/questions/3644138/secure-user-image-upload-capabilities-in-php – ajreal

+0

Brzmi bardzo dobrze dla mnie, może z wyjątkiem bardzo liberalnych uprawnień. Może mogą być nieco ograniczone? W przeciwnym razie robi to wszystko, co jest mi potrzebne, w tym usunięcie danych EXIF. –

Odpowiedz

3

Należy również sprawdzić rozmiar przesłanego pliku, ponieważ getimagesize może czasami przekraczać dostępną pamięć RAM. Dobrze jest także założyć, że skrypt może się zawiesić w dowolnym momencie (na przykład, gdy elektryczność spadnie), więc powinieneś zaimplementować pewne procedury czyszczenia, aby usunąć lewe, niepotrzebne pliki.

+1

Maksymalny rozmiar pliku do przesłania jest już ograniczony w php.ini. – Maerlyn

+0

Tak, ale to nie znaczy, że wystarczy, aby uniknąć przekroczenia limitu pamięci RAM. –

+0

Jeśli przekroczy on rozmiar w php.ini, nie otrzymasz nazwy pliku w '$ _FILES' - więc nie możesz sprawdzić jego rozmiaru. – Maerlyn

-1

To dość kompletne podejście, ale nie widzę żadnego mechanizmu zapobiegania wykonywaniu kodu.

Należy upewnić się, że zawartość obrazu nigdy nie jest zawarta (z włączeniem lub wymaganiem wywołania) lub wykonana przez eval().

W przeciwnym razie może zostać wykonany kod php na końcu pliku.

Możesz także spróbować wykryć kod php w treści obrazu (z file_get_contents, a następnie na przykład wyszukując wyrażenie "<? Php"), ale nie mogłem znaleźć w 100% bezpiecznego sposobu na wyeliminowanie podejrzanego kodu bez zniszczenia niektóre (poprawne) obrazy.

+0

Nie widzę, jak kod PHP byłby wykonywany w pliku JPG, chyba że serwer jest źle skonfigurowany? –

+0

Nie ma sensu, ponieważ jest oczywiste, że nikt nie zadzwoni do eval ani nie zawrze obrazu. Nie mogę wymyślić żadnego scenariusza, w którym ktoś mógłby pomyśleć o zrobieniu tego (chyba że po prostu zaczął używać PHP). –

+0

Oryginalny plik zostanie usunięty, gdy tylko zostaną usunięte poprawione zdjęcia. jest używany tylko z następującymi funkcjami php w następującej kolejności: move_uploaded_file, filesize, getimagesize, imagecreatefromjpeg, imagecopyresampled. – Alex

4
  1. Katalog z chmod 0777 jest, z definicji, publicznie dostępny dla innych użytkowników zalogowanych na serwerze, a nie prywatny. Prawidłowe uprawnienia będą wynosić 700 i będą własnością: apache (lub dowolnego użytkownika, na którym działa twój serwer sieciowy). Nie jestem pewien, dlaczego nie używałbyś domyślnego katalogu tymczasowego php tutaj, ponieważ on również znajduje się poza katalogiem głównym.
  2. Biała lista jest dobrym pomysłem. Uważaj, aby mieć poprawną implementację. Na przykład wyrażenie regularne /.png/ faktycznie pasuje do apng.php.
  3. Ten krok to świetny pomysł. W zasadzie sprawdza magię pliku.
  4. Nie jest to bezwzględnie konieczne. W dwóch poprzednich krokach ustaliliśmy, że rozszerzenie i format pliku są poprawne. Jeśli potrzebujesz poprawnego typu MIME, który ma być określony przez klienta, powinieneś również sprawdzić, czy dany typ MIME i określony powyżej są równoważne.

Kroki od 5 do 8 nie są związane z bezpieczeństwem.

Krok 9: Zakładam, że Twoja strona pozwala każdemu zobaczyć każde zdjęcie. Jeśli tak nie jest, powinieneś mieć schemat URL o znacznie dłuższym adresie URL (np. Hashsum obrazu).

+1

(-1) 777 nie oznacza publicznego pod względem dostępności w sieci - o tym właśnie mówi. A twój przykład regex sugeruje, że i tak jest to jakikolwiek obraz ... a BTW exe to rozszerzenie okna ...: -/ – Raffael

+0

@ Raffael1984 Myślę, że phihag to wie. Jest nadal publiczny pod względem * dostępności dla innych użytkowników na tym samym serwerze *, co * jest * problemem. Ale zgadzam się, że krok 2) jest niepotrzebny, jeśli robisz 3) prawidłowo –

+0

@ Raffael1984 Prawda. Nie jestem pewien, dlaczego ten krok jest konieczny. Zaktualizowano odpowiedź. – phihag

Powiązane problemy