Новости · Безопасность файлов

Через загрузку картинки в Rails можно было прочитать файлы сервера

Обычная форма загрузки аватара оказалась дверью в чужой сервер. Команда Ruby on Rails закрыла критическую уязвимость в Active Storage: специально собранный файл, притворяющийся картинкой, при создании превью заставлял сервер прочитать посторонние данные — вплоть до паролей и ключей. Разбираем, при чём тут форматы файлов и какой из этого урок.

7 августа 2026 Редакция LoadFile Чтение 7 мин
Треснувший значок файла-картинки, из которого утекают потоки данных и раскрытые замки над серверной стойкой

Коротко: в Rails Active Storage нашли критическую уязвимость CVE-2026-66066 (оценка 9,5 из 10). Загруженный злоумышленником файл при создании превью через библиотеку libvips читал произвольные файлы сервера — вплоть до секретных ключей и запуска чужого кода. Исправление вышло в начале августа 2026 года; лечится обновлением и блокировкой недоверенных загрузчиков.

Что произошло

В конце июля — начале августа 2026 года команда безопасности Ruby on Rails выпустила экстренные обновления против уязвимости CVE-2026-66066. Проблему опубликовали 29 июля через рекомендацию GHSA-xr9x-r78c-5hrm, а массово о ней написали 1 августа. По шкале CVSS 4.0 ей присвоили 9,5 из 10 — почти максимум. Исследователи из компаний Ethiack и GMO Flatt Security, нашедшие брешь, дали ей запоминающееся имя KindaRails2Shell.

Rails — один из самых распространённых веб-фреймворков, на нём работают тысячи сайтов и сервисов. Уязвимость затрагивает его штатный модуль Active Storage, который отвечает за приём и хранение загружаемых пользователями файлов: аватаров, вложений, фотографий в объявлениях. Именно то место, где сайт принимает картинку от постороннего, и оказалось слабым звеном.

Как картинка превращалась в кражу файлов

Когда сайт на Rails принимает изображение, он обычно тут же готовит его уменьшенные версии — превью и миниатюры. За эту обработку часто отвечает быстрая библиотека libvips. Проблема была в небезопасной настройке по умолчанию (класс CWE-1188): Active Storage передавал недоверенный файл в libvips, не отключая «нефаззенные» загрузчики — то есть код чтения редких и толком не проверенных на устойчивость форматов.

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

  1. Подмена типа. Через прямую загрузку злоумышленник создавал объект с ложным типом содержимого (content-type), выдавая свой файл за изображение.
  2. Запуск обработки. Сайт получал подписанный ключ варианта и запускал генерацию превью — libvips начинал «разбирать» файл.
  3. Хитрый формат. Файл маскировался под старый научный формат MATLAB (Level 5), но на деле содержал контейнер MAT 7.3 на базе HDF5. А в HDF5 есть механизм «внешних файлов» (External File List), позволяющий подтянуть данные из другого файла на диске.
  4. Чтение чужого. Через этот механизм libvips считывал байты из указанного атакующим пути на сервере и «отрисовывал» их как пиксели картинки. Открыв полученное превью, злоумышленник фактически видел содержимое постороннего файла.

Ключевая мысль: файл притворялся безобидным изображением, но за счёт вложенного «неожиданного» формата вынуждал обработчик читать то, что читать не следовало. Всё это — без входа в систему и без пароля: достаточно было уметь загрузить файл.

Чем это опасно

Возможность прочитать любой файл на сервере — это не только утечка документов. Через неё атакующий добирался до самого чувствительного:

  • переменные окружения процесса Rails;
  • главный ключ приложения secret_key_base и мастер-ключ Rails;
  • пароли к базе данных;
  • ключи доступа к облачным хранилищам и сторонние API-токены.

Заполучив secret_key_base, злоумышленник, по словам исследователей, получает «мастер-ключ приложения»: им можно подделывать сессии и подписанные данные, а оттуда — выйти на выполнение произвольного кода (RCE) и перемещение внутри инфраструктуры. Поэтому одного лишь обновления мало — все засветившиеся секреты нужно менять.

!
Главный вывод

«Картинка» — это просто набор байтов, а обработчик доверяет её содержимому. Если программа готова разбирать любой вложенный формат, злоумышленник подсунет тот, который заставит её сделать лишнее. Безопасна не «картинка вообще», а строго ограниченный список того, что вы соглашаетесь читать.

Как чинят и что делать

Исправление выпущено для поддерживаемых веток фреймворка. Если вы сопровождаете проект на Rails, порядок такой:

  1. Обновите Active Storage до версий 7.2.3.2, 8.0.5.1 или 8.1.3.1 (в зависимости от вашей ветки). Rails 6.x официального патча не получил — это дополнительный повод уходить со снятых с поддержки версий.
  2. Проверьте libvips. Нужна версия 8.13 или новее, а привязка ruby-vips — 2.2.1+. Только там доступна защита от недоверенных загрузчиков.
  3. Заблокируйте недоверенные форматы. Как временную меру включите VIPS_BLOCK_UNTRUSTED или вызовите Vips.block_untrusted(true) в инициализаторе — это отключает разбор редких «нефаззенных» форматов.
  4. Смените все секреты, которые могли утечь: secret_key_base, пароли БД, ключи облачных хранилищ и API-токены. Смена secret_key_base заодно завершит активные сессии.

Отдельно отметим: пользователей, у которых обработкой занимается ImageMagick, а не libvips, этот конкретный вектор не затрагивает — но общий принцип «не доверяй содержимому загруженного файла» верен для любого обработчика.

Урок для всех, кто работает с файлами

История Rails — частный случай большой закономерности, о которой на Loadfile мы пишем постоянно: расширение и заявленный тип файла ничего не гарантируют. Внутри «картинки» может лежать совсем другой формат, а обработчик, который слепо доверяет содержимому, становится оружием против самого сервера.

Что из этого стоит вынести:

  • Проверяйте реальный формат, а не расширение. Понять, что за файл перед вами на самом деле, помогает определение формата по сигнатуре, а список рискованных типов собран в карте опасных расширений.
  • Файл несёт больше, чем видно. Даже безобидная фотография хранит скрытые слои — например, метаданные EXIF, — а иногда в неё прячут и вредоносный код.
  • Ограничивайте, что разрешено разбирать. Чем меньше форматов принимает система, тем меньше поверхность атаки. Базовые правила безопасной работы с загрузками собраны в разделе безопасность файлов.

Это уже не первый случай, когда безобидный с виду файл-картинка оказывается вектором атаки: недавно вредоносный код прятали прямо в PNG в кэше браузера, а сама библиотека libvips уже спотыкалась на форматах TIFF и GIF. Вывод один: доверять файлу можно ровно настолько, насколько вы контролируете, что именно ваша программа готова в нём прочитать.

Источники

Читайте также