LiteLLM: утёкший master key привёл к краже токенов GitHub и вредоносному релизу 1.107.0

В конце мая 2026 года в публичный репозиторий LiteLLM-Labs/lite-harness попал конфигурационный файл с master key от развёртывания LiteLLM Agent Platform — открытого инструмента оркестрации агентов. Ошибку заметили быстро, коммит перезаписали через force-push, а скомпрометированные ключи признали подлежащими отзыву. Отзыв master key при этом так и не выполнили. Этим ключом 10 октября 2026 года воспользовался неизвестный атакующий, работавший с адреса 69.48.229[.]143, и добрался до OAuth-токена GitHub CLI, который сервис использовал, чтобы самостоятельно создавать pull request в репозитории.

Токен, по словам разработчиков LiteLLM, не был ограничен по правам и принадлежал владельцу GitHub-организации. Это дало атакующему доступ уровня владельца ко всем репозиториям организации и возможность выкачивать дополнительные учётные данные. Дальше события развивались как классическая атака на цепочку поставок: подмена release-пайплайна, публикация вредоносного пакета и его карантин.

Хронология атаки на LiteLLM

  • 10 октября 2026, 22:11–22:12 UTC: атакующий коммитит во временные ветки внутренних репозиториев BerriAI/litellm и BerriAI/litellm-auto, чтобы запустить workflow, добывающие OAuth-токены GitHub CLI двух инженеров с правами maintainer, через подконтрольный ему endpoint webhook[.]site. Оба запуска удаляются через несколько минут.
  • 21 октября 2026, 10:08–11:08 UTC: обход защиты ветки и правка release-пайплайна — источник подменён на похожий репозиторий Berri-AI/litellm вместо BerriAI/litellm.
  • 21 октября 2026, 11:39–11:40 UTC: публикация LiteLLM версии 1.107.0 в PyPI.
  • 21 октября 2026, 11:46 UTC: публикация образов в Docker Hub и GHCR.
  • 21 октября 2026, 11:53–11:54 UTC: удаление записей о запусках в production и staging.
  • 21 октября 2026, 12:06 UTC: исследователь Lidor Machluf из Upwind сообщает об атаке на цепочку поставок.
  • 21 октября 2026, 13:23 UTC: PyPI помещает LiteLLM 1.107.0 в карантин.
  • 21 октября 2026, 14:20 UTC: теги Docker Hub v1.107.0, latest, main-latest и main-stable удалены или перенаправлены на проверенные чистые образы.

В обычном режиме сборку и публикацию релиза запускает авторизованный инженер, а подтверждает специальный аккаунт, привязанный к физическому устройству в офисе компании. «Это ограничение ослабили ранее на этой неделе, чтобы временно увеличить частоту релизов и бэкпортов исправлений: теперь запускать и подтверждать релиз могли любые два инженера. Атакующий использовал один токен, чтобы запустить релиз после перенаправления деплоера на свой репозиторий, и второй — чтобы его подтвердить», — говорится в сообщении LiteLLM. Там же отмечают: имея токен владельца организации, злоумышленник мог и сам ослабить или вовсе снять это ограничение — вероятно, он этого не делал, чтобы не привлекать внимания.

Что нашли в workflow

Компания Socket, разбиравшая вредоносные workflow, восстановила два коммита, каждый из которых добавлял workflow в файл .github/workflows/cache.yml. Первый сделан 10 октября 2026 года в 22:11:45 UTC, второй — 12 октября. «Ни один из коммитов не попал в ветку, которая существует до сих пор. Оба ушли в короткоживущие ветки с именами вида ci-tmp-, созданные, использованные и удалённые за считанные минуты, поэтому в обычной истории репозитория почти ничего не остаётся», — рассказал исследователь Socket Карло Занки.

Оба коммита опирались на легитимный коммит как базу ветки, чтобы push выглядел безобидно. Схема повторялась: создать временную ветку ci-tmp- (например, ci-tmp-a351cc и ci-tmp-4d8517) от свежего настоящего коммита, запушить коммит с добавлением .github/workflows/cache.yml под одним и тем же заголовком «ci: bump cache config», дождаться запуска workflow по триггеру on: [push] и удалить ветку.

Оба workflow собирали токены GitHub и API-ключи для рабочего пространства организации в Linear, развёртывания LiteLLM и Together AI, а также идентификатор и ключ подписи GitHub App. Запуск 12 октября расширил сбор: API-ключи Anthropic, OpenAI, AWS Bedrock, Tavily и тенанта GitGuardian для сканирования секретов, состояние хранилища Playwright, данные PostgreSQL (строка подключения, имя учётной записи, пароль), адрес, порт и пароль аутентификации Redis. Собранное уходило на два endpoint:

webhook[.]site/65a42464-3cfa-4b02-a18c-17a6d7b86f37
webhook[.]site/4da03473-a3e7-4dc2-a087-9c564b4208e1

«Токен GitHub и приватный ключ GitHub App — это учётные данные платформы, где лежит репозиторий, а не стороннего сервиса. GITGUARDIAN_API_KEY — учётные данные самой платформы сканирования секретов: они дают атакующему видимость и потенциально контроль над оповещениями, которые должны были бы выявить эту активность. E2E_LINEAR_STORAGE_STATE_B64 — сериализованное состояние браузерной сессии для end-to-end тестов Playwright; валидное состояние даёт доступ к аккаунту Linear без пароля и без прохождения многофакторной аутентификации», — пояснил Занки.

Находки опровергли первоначальную гипотезу LiteLLM о том, что OAuth-токены GitHub CLI украли из логов внутреннего развёртывания. «Расследование было процессом, в котором мы постоянно узнавали новое, поэтому некоторые наши допущения и представления позже оказались неточными или неполными», — признал Дженсен.

Что делает вредоносная версия LiteLLM 1.107.0

Файлы пакета LiteLLM 1.107.0 запускаются автоматически при старте Python — даже если приложение не импортировало LiteLLM. У вредоносной версии две ветки исполнения: модуль сбора учётных данных по инструментам разработчика, ИИ-приложениям, облачным средам и браузерам и Unix-бэкдор, который работает фоновым процессом и раз в час забирает и выполняет произвольный код с сервера атакующего.

Стилер собирает сведения о системе, SSH-файлы, учётные данные и токены Git и GitLab, переменные окружения, токены npm, PyPI, pip, Yarn, Maven, Gradle, Composer, RubyGems и Cargo. Данные упаковываются и отправляются HTTP POST-запросом на litellm[.]dev/healthcheck — домен зарегистрирован 13 октября 2026 года.

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

Что делать администратору

Если в вашей инфраструктуре использовался LiteLLM 1.107.0, проверьте не только каталог приложения, но и файлы автозапуска Python, а также ветки и workflow в репозиториях. Удаление пакета само по себе не гарантирует очистку. Стоит отозвать токены GitHub, ключи API облачных ИИ-сервисов, учётные данные PostgreSQL и Redis, ключи пакетных менеджеров, если они находились в заражённой среде. Отдельно проверьте оповещения GitGuardian: ключ от платформы сканирования секретов тоже попал в руки атакующего.

Атака на release-пайплайн LiteLLM перекликается с другими случаями компрометации цепочек поставок: например, когда атакующие подменили серверы обновлений AOMEI и оставили бэкдор SHINYROAD. Общая черта — доверие к автоматике сборки и публикации, которую никто не перепроверяет вручную. В случае с LiteLLM роковую роль сыграли два фактора: неотозванный master key и временно ослабленное правило подтверждения релиза.

Частые вопросы

Кого касается эта история?

Всех, кто использует LiteLLM — особенно версию 1.107.0 — и тех, в чьих репозиториях или CI-системах хранились токены GitHub, ключи облачных ИИ-сервисов и доступы к PostgreSQL и Redis в одной среде с Python.

Как проверить, не попал ли ко мне вредоносный пакет?

Проверьте установленную версию LiteLLM: 1.107.0 опубликована 21 октября 2026 года и в тот же день помещена в карантин PyPI. Ищите файл .github/workflows/cache.yml в репозиториях и временные ветки вида ci-tmp- в истории.

Достаточно ли удалить пакет LiteLLM?

Нет. По данным Microsoft Security Research, файлы автозапуска лежали вне каталога приложения, поэтому удаление только файлов LiteLLM может оставить вредоносные компоненты на месте. Нужно проверять автозапуск Python отдельно.

Какие учётные данные могли утечь?

Токены GitHub и GitHub App, ключи Linear, Together AI, Anthropic, OpenAI, AWS Bedrock, Tavily, GitGuardian, данные PostgreSQL, адрес и пароль Redis, состояние сессии Playwright, токены npm, PyPI, pip, Yarn, Maven, Gradle, Composer, RubyGems и Cargo, SSH-файлы и переменные окружения.

Как атакующий обошёл защиту веток?

Он использовал токен, принадлежавший владельцу GitHub-организации, — такой уровень доступа позволял менять release-пайплайн и обходить ограничения. Кроме того, компания сама временно ослабила правило: релиз могли запускать и подтверждать любые два инженера вместо аккаунта, привязанного к физическому устройству в офисе.

Почему отзыв master key не выполнили сразу?

В сообщении LiteLLM сказано, что ошибку быстро нашли, коммит перезаписали и определили ключи как требующие отзыва. Однако отзыв master key так и не произошёл — причину компания не раскрывает.

Опасен ли LiteLLM сейчас?

Вредоносную версию 1.107.0 поместили в карантин PyPI, а теги Docker Hub v1.107.0, latest, main-latest и main-stable удалили или перенаправили на проверенные чистые образы. Компания заявила, что отзывает токены, связанные с каждой внутренней системой и платформой вендоров.

Связана ли эта атака с другими инцидентами в цепочке поставок?

Прямой связи в отчёте не указано. Но схема — компрометация пайплайна сборки и публикация вредоносного пакета — повторяет подход, который использовался и в других громких случаях, включая подмену обновлений AOMEI и уязвимости в релизных процессах вроде критического RCE в GitLab с CVSS 10.0.

Источник: thehackernews.com