Witajcie po bardzo długiej przerwie. W wyniku kilku spraw nie mogłem znaleźć weny i czasu na naskrobanie czegoś na bloga. Nadszedł czas troszkę to nadrobić - zacznę, mam nadzieję, konkretnie.
Dziś na warsztat pójdzie sprawdzanie typu pliku na podstawie jego MIME. Jak dobrze wiadomo, sprawdzanie po rozszerzeniu jest niepewną i ryzykowną formą - rozszerzenie można zmienić, a nieraz (wskutek takiej czy innej konfiguracji serwera) można wykonać plik zamaskowany rozszerzeniem .jpg jako normalny plik PHP. Potencjalnych skutków chyba nie trzeba opisywać ;) Przechodząc do rzeczy:
1) Korzystając z klasy Fileinfo
To rozszerzenie PHP powstało właśnie do tego celu i jest aktualnie najlepszą
metodą na osiągnięcie naszego celu. Poniżej krótki i treściwy przykład
działania klasy.
<?php
$file1 = 'image.png'; // Faktyczny obrazek w PNG
$file2 = 'kod.png'; // Plik PHP ze zmienionym rozszerzeniem
$finfo = new finfo(FILEINFO_MIME);
echo $finfo->file($file1, FILEINFO_MIME_TYPE); // Wyświetli: image/png
echo $finfo->file($file2, FILEINFO_MIME_TYPE); // Wyświetli: text/x-php
W tym miejscu już doskonale widać przewagę tego rozwiązania nad sprawdzaniem rozszerzenia pliku - oszust został zdemaskowany.
2) Poprzez funkcję mime_content_type
Uwaga, ten sposób jest gorszy! Wspomniana funkcja została zdeprecjonowana,
więc nie powinno się jej używać. Jednakże dosyć często zachodzi sytuacja,
w której na serwerze nie jest dostępna pierwsza metoda (klasa fileinfo),
a możemy użyć owej funkcji - dlatego o niej wspominam.
<?php
echo mime_content_type('php.gif'); // Wyświetli: image/gif
3) Sprawdzanie typu pliku po jego zawartości Każdy typ pliku zawiera na swoim początku zestaw charakterystycznych dla niego kilku bajtów. Sprawdzając je, możemy określić typ pliku - należy jednak wspomnieć, że to właśnie z tej metody korzystają powyższe rozwiązania, więc zabawę z ręczną jej implementacją możemy rozpocząć gdy jesteśmy zdesperowani i nie mamy żadnej z powyższych możliwości.
Poniżej krótki przykład, pobranie trzech pierwszych bajtów pliku, skonwertowanie ich do postaci heksadecymalnej i porównanie ich z bajtami charakterystycznymi dla pliku MP3
<?php
$file = fopen('plik.mp3', 'r');
$bytes = bin2hex(fread($file, 3));
if($bytes == '494433') {
// Sprawdzany plik jest plkiem MP3
}
else {
// Inny plik
}
fclose($file);
Dużą listę takich charakterystycznych bajtów możecie znaleźć tutaj, można też skorzystać z serwisu FileExt.com.
Mam nadzieję, że komuś przydał się ten wpis. Dziękuję za uwagę :)
Komentarze wyłączone
Możliwość komentowania na blogu została wyłączona. Zapraszam do kontaktu na Twitterze, Facebooku lub poprzez formularz, o ten tutaj. Do usłyszenia!