2014-11-09 3 views
0

Как я могу проверить расширение загруженных файлов в следующем коде (я уже писал проверку типа файла)? Я хочу предотвратить загрузку файлов изображений с неправильным расширением, например * .jpg.exe.Как проверить расширение загружаемых файлов?

Мой код:

<?php 

class Uploader { 

    private $fileName; 
    private $fileData; 
    private $destination; 

    public function __construct($key){ 
     $this->fileName = $_FILES[$key]['name']; 
     $this->fileData = $_FILES[$key]['tmp_name']; 
    } 

    public function saveIn($folder){ 
     $this->destination = $folder; 
    } 

    public function save(){ 

     $folderWriteAble = is_writable($this->destination); 
     if($folderWriteAble && (exif_imagetype($this->fileData) == IMAGETYPE_JPEG)){ 
      $name = "$this->destination/$this->fileName"; 
      $success = move_uploaded_file($this->fileData, $name); 
     } else { 
      trigger_error("cannot write to $this->destination"); 
      $success = false; 
     } 

     return $success; 

    } 

} 
+0

Я хочу предотвратить это: http://oi62.tinypic.com/vdk6qv.jpg – enkeyz

ответ

2

При запуске на сервере (ах) Linux я бы проверить тип содержимого файла с помощью команды file, которая возвращает реальный тип пантомимы файла. Чем вы можете быть уверены, что это за контент (в большинстве случаев).

Эта программа использует магические байты. Первоначальная идея состоит в том, чтобы проверить первые байты представления и проверить, содержит ли файл известный шаблон, например. «MZ» для исполняемых файлов Windows или «‰ PNG» для png-файлов. Однако эта программа file выполняет также несколько вещей, чем только базовый набор байтов первого представления.


В зависимости от комментариев вы обеспокоены неправильным, например. двойные расширения файлов. Я бы сказал, не думайте об этом и просто переименуйте этот файл, в лучшем случае с каким-то случайным именем. Это также может быть полезно, если вы беспокоитесь о том, что кто-то просто подсчитывает некоторые номера файлов, чтобы увидеть неопубликованные изображения.

+0

Я хочу для предотвращения загрузки файлов изображений с двойными расширениями, такими как * .jpg.exe. Я уже проверял filetype с exif_imagetype(). Как кто-то хочет выгрузить действительный файл изображения с неправильным расширением: realImage.jpg.exe. Если он это сделает, exif_imagetype() вернется с IMAGETYPE_JPEG – enkeyz

+0

, потому что это действительное jpg-изображение, просто с неправильным расширением. – enkeyz

+0

@ NorbertKlár в порядке, я вижу сейчас. Вам нужно будет проверить это самостоятельно. Однако я бы предложил переименовать все файлы, которые поступают от клиентов. Очень возможно, что они содержат данные, которые пользователь не захочет публиковать. Всегда помните о перспективах секьютити * все, что есть, есть зло *, поэтому просто переименуйте этот файл, когда он действителен ;-) – rekire

0

Используйте getimagesize, который проверяет первые три бита в файле. Обратите внимание, что $ _FILES не является безопасным, поскольку он читает расширение (которое люди могут сменить, конечно), vs getimagesize, который считывает биты разрешения.

Использование:

$image = getimagesize($_FILES['image']['tmp_name']); 

$filetype = $image['mime']; 

Надеется, что это помогает

0

Я знаю, что это не будет обязательно ответьте на свой конкретный вопрос, но хороший способ предотвратить «выполнение изображений PHP» должен состоять в том, чтобы изображения отображались с места, которое не выполняет скрипты PHP, и служит только для статических изображений (то есть: nginx, если он правильно настроен) , Это может быть даже внешний CDN или просто простой каталог, который не запускает php.

Это, как говорится, вы можете также попробовать:

1- Make sure file type is (jpg, gif or png) 
2- Make sure dimensions are numbers 
3- Make sure file size does not exceed allowed size 
4- Make sure file is not executable by anyone else (proper chmod settings are important in shared environment). 
5- Rename and convert all uploads through imagemagick to jpg (or your desired format) 

Использование GD библиотеки, чтобы проверить, если ваша загрузка является JPG и, кроме того, проверьте, если она также возвращает ложь для частично загруженных изображений:

$image = @imagecreatefromjpeg($this->fileData); 
if(!$image) { imagedestroy($image); return false; } // file is not a jpg 
else { imagedestroy($image); return true; } // file is a jpg 

Если вы можете использовать exec(), вы также можете вызвать утилиту unix-файла для проверки подписи.

// verify that the file is a jpg 
$mime = "image/jpeg; charset=binary"; 
exec("file -bi " . $this->fileData, $out); 
if ($out[0] != $mime) { 
    // file is not a jpg 
    ... 

Если ClamAV установлен, вы также можете проверить на наличие вируса с ехес команды:

exec("clamscan --stdout " . $this->fileData, $out, $return); 
if ($return) { 
    // file is infected 
    ... 
Смежные вопросы