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

StackOverflow https://stackoverflow.com/questions/256172

  •  05-07-2019
  •  | 
  •  

Вопрос

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

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

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

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

Это было полезно?

Решение

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

Другие советы

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

  • Прежде всего, установите MAX_FILE_SIZE в форме загрузки , а также максимальный размер файла и < code> 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 = <Ол>
    
  • Разрешить загружать файл только авторизованным пользователям. Вы также можете добавить капчу, чтобы препятствовать примитивным ботам.

  • Прежде всего, установите MAX_FILE_SIZE в форме загрузки , а также максимальный размер файла и < code> 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 .)

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

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

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

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

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

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

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

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

    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}
    

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

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

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

    X-Download-Options: noopen
    Content-Disposition: attachment; filename=untrustedfile.html
    

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

    <*>
  • Можно иметь допустимые файлы изображений с кодом внутри них, например, в данных exif . Поэтому вы должны удалить exif из изображений , если его содержание не важно для вас. Вы можете сделать это с помощью Imagick или GD , но оба требуют переупаковки файла. Вы можете найти exiftool какFILES['image']; if ($fileInput['error'] != UPLOAD_ERR_OK) ; //handle upload error here, see http://php.net/manual/en/features.file-upload.errors.php //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 для загруженных файлов. Этот поддомен или каталог не должен выполнять какой-либо файл . Установите его в конфигурации сервера или установите в < strong> .htaccess файл по каталогу.

    <*>

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

    <*>

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

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

    <*>

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

    <*>

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

    <*>

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

    <*>
  • Можно иметь допустимые файлы изображений с кодом внутри них, например, в данных exif . Поэтому вы должны удалить exif из изображений , если его содержание не важно для вас. Вы можете сделать это с помощью Imagick или GD , но оба требуют переупаковки файла. Вы можете найти exiftool как

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

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top