Разрешить загружать файл только авторизованным пользователям. Вы также можете добавить капчу, чтобы препятствовать примитивным ботам.
Прежде всего, установите 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, 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
для загруженных файлов. Этот поддомен или каталог не должен выполнять ни один файл . Установите его в конфигурации сервера или установите в .htaccess
файле в каталоге.
SetHandler none
SetHandler default-handler
Options -ExecCGI
php_flag engine off
Установите с помощью chmod()
.
$noExecMode = 0644;
chmod($uploadedFile, $noExecMode);
Используйте chmod()
и для вновь загруженных файлов и установите его в каталоге.
Вы должны проверить тип пантомимы , отправленный хакером. Вы должны создать белый список разрешенных типов пантомимы . Разрешить только изображения , если не нужен какой-либо другой формат. Любой другой формат представляет собой угрозу безопасности. Изображения тоже, но, по крайней мере, у нас есть инструменты для их обработки ...
поврежденное содержимое , например: HTML в файле изображения может вызывать XSS в браузерах с анализом содержимого уязвимостью, Если поврежденный контент представляет собой код PHP , его можно объединить с уязвимостью evaljection .
$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
}
Если вы хотите обслуживать другие типы пантомимы , вы всегда должны принудительно загружать ими, никогда не включать их в веб-страницы, если вы действительно не знаете, что делаете ...
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 данные могут быть проблемой, если ваш сайт имеет уязвимость evaljection , например, если вы где-то используете include($userInput)
.
Никогда не используйте include()
, require()
загруженными файлами , используйте их как статические или используйте file_get_contents()
или readfile()
, или любую другую функцию чтения файлов, если хотите контролировать доступ.
Он редко доступен, но я думаю, что лучше всего использовать заголовки X-Sendfile: {filename}
с модулем sendfile apache . По заголовкам, никогда не используйте пользовательский ввод без проверки или очистки, потому что это приведет к инъекции HTTP-заголовка .
Если вам не нужен контроль доступа (что означает, что только авторизованные пользователи могут видеть загруженные файлы), предоставьте файлы вашему веб-серверу. Это намного быстрее ...
Используйте антивирь для проверки загруженных файлов, если он у вас есть.
Всегда используйте комбинированную защиту , а не просто один подход. Будет сложнее нарушить вашу защиту ...