Какой самый безопасный способ загрузки файла?
-
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)