LiteLLM 1.107.0 на PyPI заражена: воровала секреты
Коротко
21 октября 2026 года официальный релизный конвейер LiteLLM опубликовал в PyPI вредоносную версию 1.107.0: семь wheel-файлов для Linux, macOS и Windows крали учётные данные и устанавливали бэкдор. К 13:23 UTC (16:23 мск) PyPI удалил релиз, а заражённые Docker-теги были удалены или переназначены к 14:20 UTC (17:20 мск). Компания считает инцидент локализованным, расследование и ротация секретов продолжаются.
LiteLLM рекомендует считать скомпрометированным любое окружение, где после установки 1.107.0 запускался Python, и любой контейнер с заражённым образом. Временно советуют версию 1.106.2. Число скачиваний, число реально заражённых систем и объём похищенного неизвестны. Отдельный инцидент платформы Railway от 21 октября пока не связан с LiteLLM подтверждённо.
Подробно
Что произошло с LiteLLM 21 октября 2026 года?
По данным LiteLLM, релиз 1.107.0 собрал и опубликовал официальный конвейер, но из репозитория-двойника Berri-AI/litellm, который контролировал атакующий, а не из официального BerriAI/litellm. Семь вредоносных wheel-файлов загрузили в PyPI 21 октября с 11:39:51 до 11:40:13 UTC (14:39:51-14:40:13 мск). К 13:23 UTC (16:23 мск) релиз удалили.
Заражёнными оказались и официальные контейнерные теги v1.107.0, latest, main-latest и main-stable в Docker Hub и GHCR. Публикация образов началась в 11:46:56 UTC, а к 14:20 UTC (17:20 мск) теги удалили или переназначили.
Технический разбор независимо подтвердили исследователи SafeDep, JFrog, AISLE, Mend и Socket. Система AISLE обнаружила первый вредоносный wheel через 3 минуты 14 секунд после публикации. Socket извлекла из контейнера данные о происхождении сборки, где записан источник Berri-AI/litellm. Эти данные показывают, какие входные данные использовала сборка, но сами по себе не доказывают, как подмена источника была авторизована.
Как работал вредоносный код в пакете?
Каждый заражённый wheel добавлял в корень site-packages три файла: cook.pth (12 байт), cook.py (22 252 байта) и sitecustomize.py (25 509 байт). Файл cook.pth содержит команду import cook, а Python обрабатывает такие файлы при обычном запуске. sitecustomize.py тоже импортируется автоматически. Поэтому код срабатывал при старте Python, даже если программа не импортировала litellm. Запуск pip в заражённом окружении мог активировать его повторно.
Похититель cook.py собирал:
- системные сведения и переменные окружения;
- сохранённые пароли и историю браузеров;
- SSH-, GPG- и TLS-ключи;
- облачные учётные данные AWS, Azure и GCP;
- секреты Kubernetes и Docker;
- токены CI/CD, пакетных менеджеров и ИИ-инструментов.
Если в окружении была переменная DATABASE_URL, код пытался выгрузить таблицы LiteLLM_CredentialsTable и LiteLLM_ProxyModelTable с ключами провайдеров моделей.
Данные упаковывались в tar.gz, шифровались AES-256-CBC, ключ AES оборачивался RSA-4096, после чего результат уходил POST-запросом на домен-двойник www.litellm.dev/healthcheck. Официальный домен проекта - litellm.ai. По регистрационным данным, litellm.dev зарегистрировали 13 октября, за восемь дней до релиза.
Файл sitecustomize.py создавал фоновый процесс. Раз в 3600 секунд он запрашивал адрес управляющего сервера из файла в репозитории letters9813/pythonclient-test на raw.githubusercontent.com, повторно запускал сборщик и мог загрузить и выполнить произвольный Python-код. На Windows эта фоновая часть из-за os.fork() нормально не запускалась, но cook.pth и cook.py работали, поэтому такие установки тоже считаются скомпрометированными.
Как атакующие получили доступ к релизному процессу?
По хронологии LiteLLM, компрометация началась не позднее 10:08:34 UTC. Сначала учётные данные привилегированного разработчика использовали для обхода защиты ветки. Затем другой аккаунт одобрил production-релиз, а учётные данные третьего разработчика использовали для удаления записей staging- и production-workflow. Злоумышленник располагал GitHub CLI OAuth-токенами трёх разработчиков.
Происхождение токенов - версия самой компании:
Мы полагаем, что атакующий получил доступ к нашему внутреннему развёртыванию, извлёк GitHub CLI OAuth-токены из его журналов и затем использовал эти данные для компрометации релизного workflow.
Как именно атакующий проник во внутреннее развёртывание, компания не подтвердила. Она подозревает недавно исправленную уязвимость. Токены, участвовавшие в атаке, отозваны. В качестве временной меры LiteLLM удалила из GitHub-организации всех пользователей, кроме одного незатронутого, и убрала доверенные связи публичных реестров с организацией. Атакующий или группа не названы.
Почему проверка исходников не выявила заражение?
Официальный GitHub-тег v1.107.0 не содержит вредоносных файлов. Исходный архив sdist тоже не включал три файла нагрузки, хотя в его pyproject.toml была посторонняя настройка data = "cook". Заражённые файлы были только в собранных wheel-файлах и контейнерных образах. Поэтому проверка одного тега или исходного архива могла ничего не показать. Исследователи AISLE считают это примером риска проверки только репозитория.
Кого затронул инцидент и как проверить заражение?
Затронуты те, кто установил 1.107.0 из PyPI или запускал заражённые теги образов. Клиенты закрытого enterprise-реестра LiteLLM, по заявлению компании, не пострадали. Сколько раз пакет скачали и сколько систем выполнили код, неизвестно.
LiteLLM рекомендует считать скомпрометированным любое окружение, где после установки 1.107.0 запускался Python, и любой контейнер, исполнявший заражённый digest sha256:1bbcb1443bc962e45f5aad53fe3d2c30600e0379715fb6c664cdd3ac126c339e. Компания советует исходить из того, что данные ушли:
Если 1.107.0 когда-либо была установлена на узле с доступом в интернет, исходите из того, что эксфильтрация удалась.
Отсутствие cook.pth, sitecustomize.py или временных marker-файлов не доказывает, что система чиста. Marker-файл /tmp/.pc_once_72129118c59f5636c0bb при наличии подтверждает успешную отправку, но его отсутствие ничего не опровергает: он мог пропасть при очистке /tmp или удалении контейнера.
Как восстановить систему и какая версия LiteLLM безопасна?
LiteLLM рекомендует не начинать с pip. Сначала нужно удалить вредоносные файлы из site-packages через оболочку и остановить фоновый процесс. Затем следует полностью пересобрать виртуальные окружения или образы на закреплённой версии 1.106.2 и сменить все секреты, доступные заражённой машине.
SafeDep признала чистыми версию 1.106.2, релиз-кандидаты 1.107.0rc1 и 1.107.0rc2, а также пакеты litellm-proxy-extras==0.4.110 и litellm-enterprise==0.1.78. Официальный отчёт LiteLLM шире: по нему безопасны все предыдущие версии. Компания временно советует 1.106.2 либо явно закреплённую более раннюю версию.
Связан ли инцидент с Railway и мартовской атакой на LiteLLM?
Платформа Railway 21 октября отдельно сообщила об аномальной активности в системах хранения клиентских переменных окружения. Основатель Railway Джейкоб Купер написал:
Наше расследование на данный момент указывает, что неавторизованная третья сторона могла получить доступ к зашифрованным переменным окружения и для части из них - к расшифрованному содержимому.
По словам Купера, компания считает это частью серии недавних атак на платформенные компании с целью компрометации провайдеров ИИ-инференса. Railway приостановила сборки и развёртывания, сбросила OAuth-сессии и учётные данные хранилищ и к 04:17 UTC 22 октября аннулировала все Railway API-токены. Клиентам рекомендовано сменить все сохранённые переменные, API-ключи и данные приватных реестров и проверить журналы. Число затронутых клиентов, период доступа и вектор атаки не названы. По статусной странице, на 08:01 UTC (11:01 мск) 22 октября сборки были доступны для Pro- и Enterprise-пространств, а восстановление Hobby, Free и Trial продолжалось.
Подтверждённой связи между инцидентами нет: ни LiteLLM, ни Railway, ни изученные независимые исследователи не называют другую сторону и не публикуют общих индикаторов или инфраструктуры.
Это уже вторая компрометация LiteLLM в 2026 году. 24 марта вредоносные версии 1.82.7 и 1.82.8 попали в PyPI после заражения сканера Trivy в CI и кражи издательских данных. После этого 30 марта компания ввела CI/CD v2: разделение проверки и выпуска по разным репозиториям, PyPI Trusted Publishing, неизменяемые Docker-теги и подпись образов Cosign. Исследователь JFrog Security Research Гай Королевски оценивает октябрьский случай как отдельную кампанию: нагрузка и инфраструктура отличаются, а доказательств связи с TeamPCP или прежним путём доступа нет.
Финансовый ущерб, требования выкупа и штрафы по обоим инцидентам не сообщались.
Источники
- LiteLLM: https://docs.litellm.ai/blog/security-incident-oct-21-2026
- Railway: https://blog.railway.com/p/security-disclosure-wednesday-october-21st
- Railway Status: https://status.railway.com/incident/QH8L8B3E
- SafeDep: https://safedep.io/litellm-pypi-compromise-credential-stealer-backdoor/
- JFrog Security Research: https://research.jfrog.com/post/litellm-hijacked-again/
- AISLE Research Team: https://aisle.com/blog/litellm-11070-on-pypi-shipped-a-credential-stealer
- Socket Research Team: https://badge.socket.dev/blog/litellm-compromise
- Mend.io: https://www.mend.io/blog/litellm-1-107-0-compromised/
- LiteLLM (CI/CD v2): https://docs.litellm.ai/blog/ci-cd-v2-improvements
- JFrog Security Research (март 2026): https://research.jfrog.com/post/litellm-compromised-teampcp/
Рубрики: Киберинциденты, Кибербезопасность, Разработка ПО и DevOps
Теги: Кибербезопасность, Киберпреступность, Программное обеспечение, Информационные технологии, Мошенничество, Происшествия, Расследования, LiteLLM, PyPI, атака на цепочку поставок, кража учётных данных, бэкдор, Docker Hub, GHCR, Railway, ИИ-шлюз, GitHub, облачные ключи, OAuth-токены, вредоносный пакет