Проверить расширение файла на Symfony3

Я хочу проверить расширение файла на Symfony3 перед загрузкой файла. До сих пор я использую этот код (это упрощенная версия, просто используемая в качестве фрагмента):

if ($form->isSubmitted() && $form->isValid()) {
    $form->handleRequest($request);
    $file = $form->get('file')->getData();
    $ext = $file->guessExtension();
    if($ext !== 'myextension' ){
        die('not allowed');
    }

    $name = md5($file->getClientOriginalName().time());
    $full_name = $name.'.'.$ext;
    $dir = __DIR__.'/../../../web/upload';
    $file->move($dir,$full_name);
}

Вопрос: файл все равно будет загружен во временную директорию? это безопасно? есть ли лучший способ сделать это? Больше всего меня беспокоит, что кто-то пытается загрузить бинарный файл или скрипт. Спасибо

РЕДАКТИРОВАТЬ (спасибо Габриэлю Диезу): файл является собственностью объекта. Я использовал assert, чтобы объявить это:

   /**
     * @Assert\File(maxSize="20M")
     */
    private $file;

person Community    schedule 03.08.2017    source источник
comment
Является ли этот файл свойством сущности?   -  person Gabriel Diez    schedule 04.08.2017
comment
Верно, я использовал его как утверждение: /** * @Assert\File(maxSize=20M) */ private $file;   -  person    schedule 04.08.2017
comment
Расширение файла — это всего лишь строка в имени. Отметив его, вы не избавитесь от пользователей, загружающих практически любые файлы. Если вы хотите быть в безопасности, поместите его где-нибудь, где он не может быть выполнен веб-сервером. Тема популярная, вопросов по загрузке файлов довольно много.   -  person svgrafov    schedule 04.08.2017


Ответы (1)


Я думаю, что лучший способ сделать это — защитить его с помощью Symfony. Поскольку этот файл является частью объекта, вы можете использовать аннотацию Assert/File, чтобы добавить некоторые ограничения и безопасность.

/**
 * @Assert\File(
 *     maxSize = "20M",
 *     mimeTypes = {"application/pdf", "application/x-pdf"},
 *     mimeTypesMessage = "Please upload a valid PDF"
 *     )
 */
private $file;

С этим Symfony обработает это на стороне сервера и вернет пользователю ошибку, если тип не разрешен. Кроме того, с помощью этого метода вы уверены, что пользователи могут загружать только доступные типы файлов.

Вы можете найти список существующих типов mime здесь и список всех ограничений symfony доступен здесь.

person Gabriel Diez    schedule 03.08.2017
comment
Обратите внимание, что если вы загрузите php-файл, который генерирует действительный PDF-файл, загрузка будет выполнена, потому что его MIME-тип будет рассматриваться как application-pdf. Лучше объединить @Assert и проверку расширения. (Я думаю, это поведение зависит от конфигурации сервера) - person v.nivuahc; 18.03.2019