Подтвердить что ты не робот

Каков наиболее безопасный способ для загрузки файла?

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

Я пытаюсь настроить серию сценариев загрузки "plug-and-play-type" для использования внутри компании, которые дизайнер может скопировать в свою структуру сайта, изменить несколько переменных и иметь готовые к использованию загрузить форму на свой сайт. Мы стремимся максимально ограничить нашу экспозицию (мы уже закрыли команды fopen и shell).

Я искал сайт в течение последнего часа и нашел много разных ответов, касающихся конкретных методов, которые полагаются на внешние источники. Что вы считаете лучшим решением script, которое достаточно конкретно для использования в качестве надежного метода защиты? Кроме того, я бы хотел, чтобы язык был ограничен PHP или псевдокодом, если это возможно.

Изменить: Я нашел свой ответ (размещен ниже) и, хотя он использует команду оболочки exec(), если вы блокируете script файлы от загрузки (что решение очень хорошо), вы не столкнетесь с какими-либо проблемами.

4b9b3361

Ответ 1

Лучшим решением, IMHO, является размещение каталога, содержащего загруженные файлы вне "веб-среды", и использование script, чтобы сделать их загружаемыми. Таким образом, даже если кто-то загружает script, он не может быть выполнен, вызывая его из браузера, и вам не нужно проверять тип загружаемого файла.

Ответ 2

  • Разрешить только авторизованным пользователям загружать файл. Вы можете добавить капчу, чтобы помешать примитивным ботам.

  • Прежде всего установите MAX_FILE_SIZE в вашей форме загрузки и установите максимальный файл size и count на сервере как Что ж.

    ini_set('post_max_size', '40M'); //or bigger by multiple files
    ini_set('upload_max_filesize', '40M');
    ini_set('max_file_uploads', 10);
    

    Проверьте размер загруженных файлов:

    if ($fileInput['size'] > $sizeLimit)
        ; //handle size error here
    
  • Вы должны использовать $_FILES и move_uploaded_file(), чтобы поместить ваши загруженные файлы в нужный каталог, или если вы хотите его обработать, затем установите флажок is_uploaded_file(). (Эти функции существуют для предотвращения инъекций имени файла, вызванных register_globals.)

    $uploadStoragePath = '/file_storage';
    $fileInput = $_FILES['image'];
    
    if (fileInput['error'] != UPLOAD_ERR_OK)
        ; //handle upload error here
    
    //size check here
    
    $temporaryName = $fileInput['tmp_name'];
    $extension = pathinfo($fileInput['name'], PATHINFO_EXTENSION);
    
    //mime check, chmod, etc. here
    
    $name = bin2hex(mcrypt_create_iv(32, MCRYPT_DEV_URANDOM)); //true random id
    
    move_uploaded_file($temporaryName, $uploadStoragePath.'/'.$name.'.'.$extension);
    

    Всегда генерировать случайный идентификатор вместо использования исходного имени файла.

  • Создайте новый субдомен, например http://static.example.com или, по крайней мере, новый каталог за пределами public_html, для загруженных файлов. Этот поддомен или каталог не должен выполнять файл. Установите его в конфигурацию сервера или установите в файле .htaccess в каталоге.

        SetHandler none
        SetHandler default-handler
        Options -ExecCGI
        php_flag engine off
    

    Установите с помощью chmod().

        $noExecMode = 0644;
        chmod($uploadedFile, $noExecMode);
    

    Используйте chmod() для вновь загруженных файлов и установите его в каталог.

  • Вам следует проверить тип mime, отправленный хакером. Вы должны создать белый список допустимых типов mime. Разрешать только изображения, если какой-либо другой формат не требуется. Любой другой формат представляет собой угрозу безопасности. Изображения тоже, но по крайней мере у нас есть инструменты для их обработки...
    Например, поврежденный контент: HTML в файле изображения может вызвать XSS с помощью браузеров с уязвимостью, снижающей уровень содержимого. Когда поврежденный контент является PHP-кодом, его можно комбинировать с уязвимостью, вызванной eval injection.

    $userContent = '../uploads/malicious.jpg';
    include('includes/'.$userContent);
    

    Попробуйте избежать этого, например, используйте class autoloader вместо того, чтобы вручную вставлять файлы php...
    Обрабатывая javascript-инъекцию сначала, вы должны отключить xss и обнюхивать содержимое в браузерах. Проблемы с обнюханием контента типичны для старых msie, я думаю, что другие браузеры фильтруют их довольно хорошо. В любом случае вы можете предотвратить эти проблемы с кучей заголовков. (Не поддерживается всеми браузерами, но лучше всего на стороне клиента.)

    Strict-Transport-Security: max-age={your-max-age}
    X-Content-Type-Options: nosniff
    X-Frame-Options: deny
    X-XSS-Protection: 1; mode=block
    Content-Security-Policy: {your-security-policy}
    

    Вы можете проверить, поврежден ли файл с помощью Imagick identify, но это не означает полную защиту.

    try {
        $uploadedImage = new Imagick($uploadedFile);
        $attributes = $uploadedImage->identifyImage();
        $format = $image->getImageFormat();
        var_dump($attributes, $format);
    } catch (ImagickException $exception) {
        //handle damaged or corrupted images
    }
    

    Если вы хотите обслуживать другие типы mime, вы всегда должны принудительно загружать ими, никогда не включайте их в веб-страницы, если вы действительно не знаете, что делаете...

    X-Download-Options: noopen
    Content-Disposition: attachment; filename=untrustedfile.html
    
  • В файлах exif возможно иметь действительные файлы изображений с кодом, например. Таким образом, вы должны очистить exif от изображений, если его содержимое не важно для вас. Вы можете сделать это с помощью Imagick или GD, но для обоих из них требуется переупаковка файла. Вы можете найти exiftool в качестве альтернативы. Я думаю, что самый простой способ очистить exif - загрузка изображений с помощью GD и сохранить их как PNG с самым высоким качеством. Таким образом, изображения не потеряют качество, и тег exif будет очищен, потому что GD не сможет его обработать. Сделайте это с изображениями, загруженными как PNG тоже...
    Если вы хотите извлечь данные exif, никогда не используйте preg_replace(), если pattern или replacement принадлежит пользователю, потому что это приведет к инъекции eval... Используйте preg_replace_callback() вместо eval regex flag, если необходимо. (Общая ошибка в кодах копирования.) Данные Exif могут быть проблемой, если ваш сайт имеет уязвимость в отношении инъекций, например, если вы используете include($userInput) где-то.

  • Никогда не используйте include(), require() загруженные файлы, ставьте их или используйте file_get_contents() или readfile() или любую другую функцию чтения файлов, если вы хотят контролировать доступ.
    Он редко доступен, но я думаю, что лучший подход к использованию заголовков X-Sendfile: {filename} с модулем sendfile apache. По заголовкам никогда не используйте ввод пользователя без проверки или дезинфекции, потому что это приведет к вводу заголовка HTTP.
    Если вам не нужен контроль доступа (означает: только авторизованные пользователи могут видеть загруженные файлы), а затем обслуживать файлы с вашего веб-сервера. Это намного быстрее...

  • Используйте антивирус, чтобы проверить загруженные файлы, если он у вас есть.

  • Всегда используйте комбинированную защиту, а не только один подход. Это будет труднее нарушить вашу защиту...

Ответ 3

Использовать и настраивать Hardened-PHP создать простой script с помощью move_uploaded_file и $_ FILES суперглобальный. Самый простой script, самый безопасный он будет (по крайней мере, так же безопасен, как и запущенная версия PHP)