Сервис принимает аватар, ориентируясь только на расширение имени файла. Как тестировщик должен проверить риск выполнения загруженного содержимого?
Нужно проверить, может ли загруженный файл попасть в область, где сервер интерпретирует его как исполняемый, а не как обычные данные. Расширение имени недостаточно: тест должен включать подмену расширения, MIME-типа и содержимого, после чего необходимо убедиться, что файл отклоняется либо хранится и отдается в неисполняемом контексте.
Загрузка файлов появилась как обычная бизнес-функция: пользователи должны были добавлять аватары, документы и вложения. Она создает границу доверия между непроверенными данными пользователя и файловой системой или веб-сервером приложения.
Изначально многие проверки опирались на имя файла или значение MIME-типа из запроса. Эти данные контролируются клиентом, поэтому такой подход не решает проблему подмены содержимого и опасного способа публикации файла.
Злоумышленник может отправить файл с допустимым расширением, но с другим содержимым, либо использовать формат, способный содержать активный контент. Если сервер сохраняет такой файл в исполняемой директории, он может быть обработан сервером как программа; если файл отдается браузеру небезопасно, возможны атаки на пользователя, например выполнение активного содержимого в контексте сайта.
Неверное решение может привести к удаленному выполнению кода, межсайтовому скриптингу, утечке данных или обходу ограничений доступа к загруженным объектам. Риск зависит не только от проверки файла, но и от места хранения, способа публикации и настроек сервера.
Тест начинается с проверки того, доверяет ли приложение расширению и заголовку MIME-типа. Нужно отправить файл с допустимым именем, но неподходящим содержимым, изменить MIME-тип, использовать двойное расширение, необычный регистр символов и варианты кодирования имени. Результат оценивают не только по ответу приложения, но и по фактическому способу сохранения и последующей обработки файла.
Безопасная проверка должна подтверждать ожидаемый формат по содержимому и разбору специализированной библиотекой, а не только по имени. Для изображений полезно повторно декодировать и перекодировать файл в разрешенный формат: это удаляет многие посторонние данные, хотя само по себе не заменяет остальные меры.
Файлы следует хранить вне исполняемой области, использовать непредсказуемые серверные имена и отдавать через контролируемый обработчик. Обработчик должен заново проверять авторизацию, не раскрывать лишние сведения о пути и задавать безопасный тип содержимого; для потенциально активных форматов, например SVG, требуется отдельная политика либо запрет.
Проверка расширения может использоваться как дополнительное раннее ограничение, но не как граница безопасности. Ограничения размера, антивирусная или песочничная проверка помогают снизить риск отказа в обслуживании и вредоносных вложений, однако не гарантируют безопасное выполнение файла.
Сервис принимает изображения профиля и сохраняет их в каталоге, доступном через тот же веб-сервер. Команда сначала рассматривала только расширение файла: это дешево и удобно, но проверка обходится изменением содержимого или имени и не устраняет опасность публикации активного формата.
Второй вариант — проверять MIME-тип, присланный клиентом. Он почти не добавляет защиты, поскольку отправитель полностью контролирует этот заголовок. Третий вариант — принимать только изображения, успешно декодируемые разрешенной библиотекой, перекодировать их, хранить вне исполняемой области и отдавать через отдельный контролируемый маршрут; он сложнее, но закрывает разные этапы атаки.
Выбран третий вариант с ограничением размера, отказом от SVG и серверными именами файлов. В результате файл с поддельным типом не проходил разбор, а даже принятые изображения не могли быть запущены веб-сервером как программы; отдельно тестировалась авторизация доступа к каждому загруженному объекту.
Заголовок формирует клиент, поэтому злоумышленник может указать допустимый тип для произвольного содержимого. Сервер должен проверять файл независимо от этого значения: анализировать сигнатуру, пытаться безопасно разобрать формат и учитывать допустимые особенности конкретного типа. Даже корректный MIME-типа не гарантирует безопасную публикацию файла.
Это существенно снижает риск прямого исполнения через веб-сервер, но не решает все проблемы. Нужно дополнительно контролировать авторизацию при скачивании, не допускать обход пути, безопасно формировать имя, ограничивать размер и проверять обработчики, которые могут читать файл. Если файл затем передается в уязвимый конвертер или публикуется другим маршрутом, опасность сохраняется.
Перекодирование обычно удаляет часть встроенных данных, не относящихся к пикселям, но зависит от качества и безопасности используемой библиотеки. Оно не защищает от переполнения или других ошибок в самом обработчике, не решает проблему авторизации и не делает безопасными форматы с активным содержимым. Поэтому его применяют как один слой защиты вместе с изоляцией хранения, ограничениями ресурсов и безопасной выдачей.