Перейти к содержанию

Файлы, полученные из недоверенных источников, хранятся за пределами директории веб-приложения

Описание

Это требование предполагает, что все файлы, загруженные пользователями или полученные из других недоверенных источников, не должны храниться в директориях, доступных напрямую через веб-сервер (например, в директории /var/www/html). Вместо этого, такие файлы должны быть сохранены в отдельные директории за пределами директории веб-приложения для предотвращения прямого доступа к ним через URL-адреса.

Почему это важно

  1. Защита от выполнения произвольного кода: Если загруженный файл можно открыть через веб-браузер, злоумышленник может попытаться загрузить скрипт и выполнить его на сервере.
  2. Предотвращение прямого доступа к файлам: Пользователи не должны иметь возможность напрямую обращаться к загруженным файлам через веб-сервер. Например, если файл загружен в директорию, доступную по HTTP, злоумышленник может получить к нему доступ или даже манипулировать содержимым.
  3. Усиление безопасности системы: Хранение файлов за пределами веб-директории снижает риск эксплуатации уязвимостей, связанных с манипуляциями с файлами (например, через LFI — Local File Inclusion или RFI — Remote File Inclusion).
  4. Ограничение доступа к конфиденциальным данным: Если файл содержит конфиденциальные данные, важно предотвратить возможность его случайного или намеренного скачивания через публичные 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, а также предоставляет злоумышленникам возможность загрузить и выполнить вредоносные скрипты.

Причины, к которым может привести несоблюдение требования

  1. Выполнение вредоносного кода: Если файлы могут быть выполнены на сервере, злоумышленник может загрузить и выполнить скрипт, что приведёт к компрометации системы.
  2. Неавторизованный доступ к конфиденциальным данным: Если пользователь загружает файл, содержащий конфиденциальную информацию, и этот файл оказывается доступным через URL, любой может получить к нему доступ.
  3. Риски безопасности при загрузке файлов: Несоблюдение этого требования увеличивает риск атак, связанных с файловыми инъекциями (LFI, RFI), когда злоумышленники могут использовать загруженные файлы для выполнения произвольного кода или получения доступа к системным файлам.

Рекомендации

  • Храните загруженные файлы за пределами веб-директории: Используйте директории вне веб-доступной области, чтобы исключить возможность прямого доступа к файлам через веб-сервер.
  • Предоставляйте доступ к файлам через контроллеры: Доступ к файлам должен контролироваться серверными скриптами, которые проверяют права доступа и корректность запросов.
  • Запрещайте выполнение скриптов в директории с загруженными файлами: Если по каким-то причинам файлы необходимо хранить в веб-директории, убедитесь, что веб-сервер настроен на запрет выполнения любых загруженных файлов.
  • Регулярно проверяйте и очищайте загруженные файлы: Убедитесь, что на сервере не остаются потенциально опасные файлы, и очищайте их, если они больше не нужны.

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