Файлы, полученные из недоверенных источников, хранятся за пределами директории веб-приложения
Описание
Это требование предполагает, что все файлы, загруженные пользователями или полученные из других недоверенных источников, не должны храниться в директориях, доступных напрямую через веб-сервер (например, в директории /var/www/html
). Вместо этого, такие файлы должны быть сохранены в отдельные директории за пределами директории веб-приложения для предотвращения прямого доступа к ним через URL-адреса.
Почему это важно
- Защита от выполнения произвольного кода: Если загруженный файл можно открыть через веб-браузер, злоумышленник может попытаться загрузить скрипт и выполнить его на сервере.
- Предотвращение прямого доступа к файлам: Пользователи не должны иметь возможность напрямую обращаться к загруженным файлам через веб-сервер. Например, если файл загружен в директорию, доступную по HTTP, злоумышленник может получить к нему доступ или даже манипулировать содержимым.
- Усиление безопасности системы: Хранение файлов за пределами веб-директории снижает риск эксплуатации уязвимостей, связанных с манипуляциями с файлами (например, через LFI — Local File Inclusion или RFI — Remote File Inclusion).
- Ограничение доступа к конфиденциальным данным: Если файл содержит конфиденциальные данные, важно предотвратить возможность его случайного или намеренного скачивания через публичные URL.
Способы реализации с примерами
1. Хранение файлов за пределами веб-директории: Файлы должны быть загружены и сохранены в директорию, которая недоступна через веб-сервер (например, /uploads
, находящуюся вне /var/www/html
).
Пример на PHP:
// Определяем директорию для загрузки файлов за пределами веб-директории
$uploadDir = '/path/to/non-web-accessible-directory/uploads/';
// Генерация уникального имени файла
$newFileName = uniqid() . '.' . pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION);
// Перемещение загруженного файла в безопасную директорию
if (move_uploaded_file($_FILES['file']['tmp_name'], $uploadDir . $newFileName)) {
echo "File successfully uploaded.";
} else {
echo "File upload failed.";
}
2. Доступ к файлам через контроллер или специальный скрипт: Если необходимо предоставить доступ к загруженным файлам пользователям, это должно происходить через контроллер на стороне сервера, который валидирует запросы и предоставляет доступ только к допустимым файлам.
Пример в Laravel:
public function download($filename) {
$path = storage_path('app/uploads/' . $filename);
// Проверка существования файла
if (!File::exists($path)) {
abort(404);
}
// Возвращаем файл через контроллер
return response()->download($path);
}
3. Конфигурация веб-сервера для защиты загруженных файлов: Важно настроить веб-сервер таким образом, чтобы он не позволял выполнять файлы, загруженные пользователями, даже если они находятся в директории веб-приложения.
Пример конфигурации в .htaccess
для Apache:
<Directory "/path/to/uploads">
# Запрет на выполнение любых скриптов
php_flag engine off
Options -Indexes
Order Deny,Allow
Deny from all
</Directory>
Примеры уязвимого кода
// Пример уязвимого кода, который сохраняет файлы прямо в веб-директорию
move_uploaded_file($_FILES['file']['tmp_name'], '/var/www/html/uploads/' . $_FILES['file']['name']);
Проблема: Загруженные файлы сохраняются в директории, доступной через веб-сервер, что позволяет пользователям напрямую получить к ним доступ по URL, а также предоставляет злоумышленникам возможность загрузить и выполнить вредоносные скрипты.
Причины, к которым может привести несоблюдение требования
- Выполнение вредоносного кода: Если файлы могут быть выполнены на сервере, злоумышленник может загрузить и выполнить скрипт, что приведёт к компрометации системы.
- Неавторизованный доступ к конфиденциальным данным: Если пользователь загружает файл, содержащий конфиденциальную информацию, и этот файл оказывается доступным через URL, любой может получить к нему доступ.
- Риски безопасности при загрузке файлов: Несоблюдение этого требования увеличивает риск атак, связанных с файловыми инъекциями (LFI, RFI), когда злоумышленники могут использовать загруженные файлы для выполнения произвольного кода или получения доступа к системным файлам.
Рекомендации
- Храните загруженные файлы за пределами веб-директории: Используйте директории вне веб-доступной области, чтобы исключить возможность прямого доступа к файлам через веб-сервер.
- Предоставляйте доступ к файлам через контроллеры: Доступ к файлам должен контролироваться серверными скриптами, которые проверяют права доступа и корректность запросов.
- Запрещайте выполнение скриптов в директории с загруженными файлами: Если по каким-то причинам файлы необходимо хранить в веб-директории, убедитесь, что веб-сервер настроен на запрет выполнения любых загруженных файлов.
- Регулярно проверяйте и очищайте загруженные файлы: Убедитесь, что на сервере не остаются потенциально опасные файлы, и очищайте их, если они больше не нужны.
Соблюдение этого требования поможет защитить ваше приложение от атак, связанных с неправильным обращением с загруженными файлами, и предотвратит доступ к чувствительным данным через общедоступные URL.