Как я могу проверить расширение загруженных файлов?

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;

    }

} 
Теги:
security
forms
file-upload
web

4 ответа

2
Лучший ответ

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

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


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

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

Я думаю, что вы уже делаете это (exif_imagetype($this->fileData) == IMAGETYPE_JPEG), но здесь есть очень хорошая дискуссия: https://security.stackexchange.com/questions/57856/is-there-a -WAY к регистрации по прибытии в-типа файлов-на-а файла-закачанный- с использованием PHP-

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 и, кроме того, проверьте, возвращает ли она также false для частично загруженных изображений:

$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 файла для проверки подписей bynary.

// 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:

exec("clamscan --stdout " . $this->fileData, $out, $return);
if ($return) {
    // file is infected
    ...
0

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

Применение:

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

$filetype = $image['mime'];

Надеюсь это поможет

Ещё вопросы

Сообщество Overcoder
Наверх
Меню