Перейти к содержимому
>_ITDITDПлатформа веб-безопасности

По фреймворкам

Безопасность Ruby on Rails — справочник по продакшн-хардингу

Справочник по продакшн-хардингу Ruby on Rails: приоритетный чек-лист плюс секреты/credentials, конфигурация, CVE gem'ов, Strong Parameters, авторизация, инъекции и SSRF. Защитно, без шагов атаки.

Опубликовано 2026-07-02 Обновлено 2026-07-02 6 мин чтения

Для: всех, кто ведёт приложение на Ruby on Rails. Здесь нет шагов атаки — это рабочий справочник по хардингу: приоритетный чек-лист, руководство по областям и самопроверка. Полную картину по фреймворкам смотрите на хабе безопасности по фреймворкам.

Приоритетный чек-лист хардинга

Проходите эту таблицу сверху вниз. P0 — предпосылка, P1 — самый частый источник инцидентов, P2 — постоянная эксплуатационная гигиена.

P0 ── Предпосылка (сначала это)

Управление секретами и credentials / продакшн-конфигурация (без раскрытия исключений, force_ssl) / быстрое закрытие CVE gem'ов

P1 ── Главный источник инцидентов

Контроль Strong Parameters/Mass Assignment / авторизация (область владельца)

P2 ── Эксплуатационная гигиена

Инъекции и опасные методы / сессии, CSRF / SSRF, загрузки

Укрепляйте от фундамента вверх: P0 (предпосылка) → P1 (главный источник инцидентов) → P2 (эксплуатационная гигиена).
ПриоритетМераКонкретика (Rails)
P0Секреты и credentialsЗашифрованные credentials + отдельный master key. Не коммитьте master key. При утечке ротируйте secret_key_base
P0Продакшн-конфигурацияНе раскрывайте детали исключений; config.force_ssl; filter_parameters, чтобы секреты не попадали в логи
P0CVE gem'ов (зависимостей)Мониторьте через bundler-audit / osv-scanner; судите по запущенной версии, быстро закрывайте
P1Strong ParametersДержите permit минимальным. Не используйте permit!. Никогда не присваивайте привилегированное поле
P1Явная авторизацияPundit / CanCanCan + authorize + область по current_user для владения
P2Инъекции/опасные методыПривязывайте в where. Не передавайте ввод в send/constantize. Не загружайте недоверенные YAML/Marshal
P2Сессии/CSRFprotect_from_forgery (по умолчанию), cookie secure/httponly/samesite, регенерация при входе
P2SSRF/загрузкиСписок разрешённых для серверных запросов + блокировка внутренних IP. Проверяйте загрузки, храните вне public/

1. Секреты и credentials (P0)

  • Используйте зашифрованные credentials Rails и не коммитьте master (расшифровочный) key в репозиторий (внедряйте через переменные окружения и т. п.).
  • secret_key_base лежит в основе подписанных/зашифрованных cookie и сессий. Немедленно ротируйте при утечке (учтите, что это делает недействительными существующие подписи/шифрование).
  • Не оставляйте .env, дампы или бэкапы в публичном каталоге (→ не держите секреты в публичных каталогах).

2. Продакшн-конфигурация (P0)

  • В продакшене не раскрывайте детали исключений (не включайте consider_all_requests_local и т. п.) — уменьшайте раскрытие внутренней структуры.
  • config.force_ssl, чтобы принудительно включить HTTPS и пометить cookie как secure. Не включайте инструменты разработки вроде web console в продакшене.
  • Используйте filter_parameters, чтобы пароли и подобное не попадали в логи.

3. CVE gem'ов (зависимостей) (P0)

4. Strong Parameters и Mass Assignment (P1)

  • Держите поля permit минимальными и избегайте permit! (разрешить всё).
  • Никогда не присваивайте привилегированное поле вроде is_admin из пользовательского ввода. Откажитесь от «разрешу широко, потому что так удобно».

5. Авторизация (P1 — главный источник)

Частое (опасное)

  • нет авторизации — «залогинен = можно смотреть/обновлять»
  • привязка маршрута к модели достаёт чужой ID
  • опора на скрытые маршруты / труднопредсказуемые ID
  • забыт authorize в некоторых действиях

Правильно

  • политика явна через Pundit / CanCanCan + authorize на каждое действие
  • чтения тоже ограничены владельцем по current_user
  • проверено на каждом пути чтения/обновления/удаления
  • авторизация построена явно, а не оставлена на значения по умолчанию

Смотрите что такое IDOR. Аутентификация и авторизация различны; авторизуйте близко к данным.

6. Инъекции и опасные динамические методы (P2)

  • SQL: привязывайте через плейсхолдеры в where; никогда не стройте запросы конкатенацией строк (избегайте where("... #{params}")) (→ что такое SQL-инъекция).
  • Опасные динамические методы: не передавайте пользовательский ввод в send/public_send/constantize. Если необходимо — строго ограничивайте списком разрешённого.
  • Десериализация: избегайте загрузки недоверенных YAML/Marshal (при определённых условиях может привести к выполнению кода).
  • Не отключайте глобально защиту от CSRF (protect_from_forgery); используйте токен формы (→ что такое CSRF).
  • Установите secure/httponly/samesite на cookie/сессии и регенерируйте сессию при входе.

8. SSRF, загрузки, заголовки (P2)

  • Серверная выборка URL, заданных пользователем, должна ограничивать цели списком разрешённого и блокировать доступ к внутренним IP/метаданным (→ что такое SSRF).
  • Проверяйте загрузки (тип/размер), храните вне public/ и не давайте прав на исполнение.
  • Добавьте заголовки безопасности (проверьте свой сайт через проверку заголовков безопасности).

Проверьте: действительно ли ваш Rails укреплён?

Собрать — ещё не конец: работа сделана только после проверки. Это защитные самопроверки против собственной среды.

1

Секреты не раскрыты/не закоммичены

Убедитесь, что master.key нет в репозитории и что .env/дампы не забираются по URL.
2

Нет деталей исключений в продакшене

Спровоцируйте ошибку и убедитесь, что детальные исключения не показываются вовне и что HTTPS принудителен.
3

Авторизация держится

В тестовой среде запросите ID ресурса другого пользователя и убедитесь, что он отклонён (чтение/обновление/удаление).
4

Зависимости и заголовки

Убедитесь, что bundler-audit/osv чист и что HTTPS/HSTS присутствуют — через проверку заголовков.

Взгляд нашего сайта: даже под защитой соглашений авторизация и зависимости на вас

Хорошие значения по умолчанию Rails снимают много риска, но авторизация — кто что может делать — и свежесть зависимостей специфичны для приложения и эксплуатации, поэтому фреймворк не может защитить их автоматически. Инциденты, которые мы видим снова и снова, — не изощрённые атаки, а тип «аутентифицирован, но нет проверки владения». Поэтому центр тяжести — проходить таблицу выше сверху вниз: затяните Strong Parameters, сделайте авторизацию явной и мониторьте gem'ы на CVE.

Читать дальше

FAQ

QЧто сделать в первую очередь для защиты Rails?
A

Три пункта P0: (1) безопасно обращайтесь с секретами (держите зашифрованные credentials отдельно от master key, не коммитьте master key; secret_key_base лежит в основе подписанных/зашифрованных cookie, поэтому при утечке — ротация); (2) укрепите продакшн-конфигурацию (не раскрывайте детали исключений; force_ssl); (3) машинно мониторьте CVE gem'ов (зависимостей) и быстро закрывайте, судя по запущенной версии. Дальше переходите к Strong Parameters и авторизации.

QНа что обращать внимание со Strong Parameters?
A

Явно разрешайте (permit), какие поля вы принимаете, чтобы предотвратить Mass Assignment (массовое присвоение непреднамеренных полей). Опасность — разрешать широко ради удобства и использовать permit! для разрешения всего. Держите разрешённые поля минимальными и никогда не позволяйте присваивать привилегированное поле вроде is_admin из пользовательского ввода.

QКак безопасно реализовать авторизацию?
A

Поверх входа (аутентификации) реализуйте проверку владения — что цель действительно принадлежит пользователю. Сделайте политику явной через Pundit/CanCanCan, вызывайте authorize в каждом действии и ограничивайте ресурсы областью current_user. Не полагайтесь на скрытые маршруты или труднопредсказуемые ID — проверяйте явно на каждом пути чтения/обновления/удаления.

QКак управлять уязвимостями gem'ов (зависимостей)?
A

Машинно мониторьте известные CVE через bundler-audit или osv-scanner и быстро закрывайте, судя по запущенной версии (решайте по фактической версии в Gemfile.lock). Держите Rails и Ruby на поддерживаемых версиях и не оставляйте EOL-версии. Свежесть зависимостей — более реалистичный фактор инцидентов, чем изощрённые атаки.

QКакие динамические методы опасны?
A

Передача пользовательского ввода в send / public_send / constantize может привести к непреднамеренному вызову метода или разрешению класса. Аналогично, загрузка через Marshal или недоверенный YAML (восстановление объектов) при определённых условиях может привести к выполнению кода. Не передавайте им данные пользовательского происхождения; если необходимо — строго ограничивайте списком разрешённого.