Я создал (используя скрипт и некоторую помощь от Stack и некоторую помощь от друзей, я очень мало знаю о PHP), простую страницу для местной некоммерческой публикации, где люди могут загружать фотографии.
Я не уверен в безопасности (из-за незнания, а не из-за небрежности), но я предпринял следующие шаги для защиты этой страницы:
• PHP-скрипт настроен только для приема файлов .jpg, .png и .tif для загрузки;
• вложенная папка, в которой сохраняется содержимое формы, имеет разрешения, установленные на уровне 700, а вложенная папка, в которой хранятся загруженные фотографии, имеет разрешения, установленные в 700;
• согласно документации, мой хост имеет следующую конфигурацию, чтобы гарантировать, что только .php-файлы выполняются как .php:
<FilesMatch \.php$> SetHandler php52-fcgi </FilesMatch>
• Я поместил файл .htaccess в соответствующие (основной и сохраненный контент) папки:
RemoveHandler .php RemoveHandler .inc RemoveHandler .pl RemoveHandler .cgi RemoveHandler .py RemoveHandler .fcgi
Ночью, однако, кто-то нашел эту тестовую страницу и представил то, что кажется совершенно доброкачественным тестовым сообщением и маленьким .jpg. Это приватная тестовая страница с неинтуитивным URL, о котором знают только я и около трех других людей; никто из других не отправил это испытание.
Это, очевидно, меня беспокоит, что происходит что-то странное, и я беспокоюсь, что не знаю достаточно о безопасности, чтобы убедиться, что эта страница в безопасности.
Есть ли что-то очевидное, что мне не хватает?
При работе с загруженными вы должны иметь в виду, что все данные, которые вы можете найти в массиве $ _FILES, можно подделать. Он перемещается по HTTP, поэтому довольно легко придать образ / jpg mime исполняемому файлу.
1- Проверить истинный мим
PHP поставляется с некоторой функцией для проверки реального mime файла. Для этого вы должны использовать fileinfo
$finfo = new finfo(FILEINFO_MIME, "/usr/share/misc/magic"); $filename = "/var/tmp/afile.jpg"; echo $finfo->file($filename);
2- Проверить свойства изображения
Вы, видимо, хотите загрузить только изображение, поэтому полученный файл должен иметь ширину и высоту:
Используйте getImageSize (), чтобы получить всю необходимую информацию об изображении. Если он возвращает false, файл, вероятно, не является изображением, и вы можете его удалить. getImageSize также может дать вам тип mime, но я не знаю, можно ли ему доверять.
2.5 – Обратное изображение
Как было предложено пользователем628405, переработка изображения с помощью GD, вероятно, является более безопасной задачей.
$img = imagecreatefrompng('vulnerable.png'); imagepng($img, 'safe.png');
Очевидно, что он должен быть адаптирован в соответствии с типом изображения. Просмотреть всю документацию в документации php.
3- Загрузить папку В дополнение к тому, что вы уже сделали:
Убедитесь, что ваша загрузочная папка недоступна из Интернета. Подтвердите загруженный файл и при необходимости переместите его в другую папку и переименуйте файл. Это предотвратит выполнение хакером вредоносного файла (его невозможно выполнить, если он не может быть достигнут URL-адресом).
Дальнейшее чтение: https://www.owasp.org/index.php/Unrestricted_File_Upload
Не полагайтесь на данные с клиента, включая тип контента!
Не сохраняйте загруженные файлы в корневом каталоге. Загруженные файлы должны быть доступны только через ваши скрипты для лучшего контроля.
Не сохраняйте загруженные файлы с их исходными именами файлов и расширениями! Сохраните эти данные в базе данных для последующего поиска.
Вы можете проверить тип файла MIME, но не волнуйтесь, пока ваш обработчик php может выполнять только файлы .php, и вы заботитесь о том, чтобы не сохранять загруженные .php-файлы в свой скрипт, вы не подвергаете утечка безопасности.
Это допустимо для файлов .php, а также для любого другого языка сценариев на сервере, установленного на вашем сервере.
Лучше всего сохранить белый список расширений, которые вы принимаете для сохранения в своей файловой системе.
Я бы проигнорировал тип MIME и расширение файла входящего файла. Их можно подделать.
Храните эти файлы в каталоге, если вы идете по этому проспекту.
Убедитесь, что этот каталог предназначен только для изображений (музыки), а затем получите скрипт, чтобы разместить на них правильное расширение, просмотрев формат файлов.
Также убедитесь, что этот каталог не может выполнять PHP (или что-то еще).
Это будет держать вас в безопасности.