LiteLLM supply chain attack: пошаговый разбор атаки и чеклист защиты API-ключей
24 марта 2026 года группа TeamPCP скомпрометировала LiteLLM через уязвимость в CI/CD-пайплайне. Вредоносные версии 1.82.7 и 1.82.8 крали SSH-ключи, облачные credentials и API-токены всех LLM-провайдеров. Разбираю цепочку атаки и даю пошаговый чеклист защиты.
24 марта 2026 года в 10:39 UTC на PyPI появилась версия LiteLLM 1.82.7. Через 13 минут — 1.82.8. Обе содержали credential stealer, который крал SSH-ключи, AWS/GCP/Azure-токены, Kubernetes-секреты, криптокошельки и переменные окружения. По данным BleepingComputer, число эксфильтраций достигло примерно 500 000.
Ирония: атаку обнаружили не сканеры безопасности, а баг в самом вредоносном коде — fork bomb, который крашил машины.
Что такое LiteLLM и почему это важно
LiteLLM — open-source Python-библиотека, унифицирующая доступ к 100+ LLM-провайдерам через единый API. OpenAI, Anthropic, Google, DeepSeek — один интерфейс вместо десяти SDK. 3,4 миллиона установок в день. 95 миллионов за последний месяц. 2000+ пакетов зависят от LiteLLM, включая DSPy и MLflow.
Когда компрометируют такой пакет — это не локальный инцидент. Это каскадная атака на всю AI-инфраструктуру.
Цепочка атаки: от Trivy до ваших ключей
Шаг 1: компрометация Trivy
TeamPCP начали не с LiteLLM. Они атаковали Trivy — сканер уязвимостей от Aqua Security. Скомпрометированный GitHub Action Trivy стал троянским конём для любого CI/CD-пайплайна, который его использовал.
Шаг 2: кража PyPI-токена
LiteLLM использовал Trivy в своём CI/CD без пиннинга версий. Скомпрометированный action извлёк PYPI_PUBLISH токен из среды GitHub Actions runner. Одна непиннированная зависимость — и атакующие получили право публиковать пакеты от имени LiteLLM.
Шаг 3: публикация вредоносных версий
С украденным токеном TeamPCP опубликовали две версии:
- 1.82.7 (10:39 UTC): вредоносный payload внедрён в litellm/proxy/proxy_server.py — base64-encoded код, который декодируется и выполняется при импорте модуля.
- 1.82.8 (10:52 UTC): добавлен файл litellm_init.pth — Python автоматически обрабатывает все .pth-файлы при старте интерпретатора. Вредоносный код выполняется при запуске любого Python-процесса, даже если LiteLLM не импортируется.
Шаг 4: трёхфазная эксфильтрация
По данным Endor Labs, payload работал в три стадии:
- Сбор credentials: SSH-ключи, облачные токены, Kubernetes-секреты, крипто-кошельки, .env-файлы, базы данных, TLS-ключи, CI/CD-секреты.
- Lateral movement: развёртывание привилегированных подов на каждом узле Kubernetes-кластера.
- Персистенция: установка systemd-сервиса под видом «System Telemetry Service», который периодически подключается к checkmarx[.]zone для загрузки дополнительных payload'ов.
Собранные данные шифровались, упаковывались в tpcp.tar.gz и отправлялись на models.litellm[.]cloud — домен, не имеющий отношения к BerriAI.
Что делало .pth-файл особенно опасным
Механизм .pth-файлов в Python — малоизвестная, но мощная точка атаки. Когда Python стартует, он сканирует директорию site-packages и выполняет строки из .pth-файлов, начинающиеся с import. Никакого явного импорта LiteLLM не нужно. Запустил python — и код уже работает.
Это означает, что даже если вы установили LiteLLM 1.82.8 для тестирования в одном проекте, любой другой Python-скрипт на той же машине запускал stealer. Jupyter notebook, Flask-сервер, скрипт деплоя — всё становилось вектором эксфильтрации.
Кто пострадал, а кто нет
Затронуты:
- Все, кто установил LiteLLM через pip 24 марта между 10:39 и 16:00 UTC.
- Все, кто запускал pip install litellm без пиннинга версии и получил 1.82.7 или 1.82.8.
- Docker-образы, собранные в это окно с pip install litellm без пиннинга.
- Проекты, где LiteLLM — транзитивная зависимость (AI-фреймворки, MCP-серверы, LLM-оркестраторы).
Не затронуты:
- Пользователи официального Docker-образа LiteLLM Proxy (ghcr.io/berriai/litellm) — зависимости пиннились через requirements.txt.
- Пользователи LiteLLM Cloud.
- Те, кто остался на 1.82.6 или ниже.
- Установки из GitHub-репозитория (он не был скомпрометирован).
Чеклист: что делать прямо сейчас
1. Проверить версию
pip show litellm
Если видите 1.82.7 или 1.82.8 — считайте систему скомпрометированной.
2. Найти артефакты persistence
Проверьте наличие .pth-файла: find $(python -c "import site; print(site.getsitepackages()[0])") -name "litellm_init.pth"
Systemd-сервис: ls ~/.config/systemd/user/ | grep -i sysmon
Временные файлы: ls -la /tmp/pglog /tmp/.pg_state
3. Проверить сетевую активность
Ищите исходящий трафик на models.litellm[.]cloud и checkmarx[.]zone.
4. Ротировать ВСЕ секреты
Не только API-ключи LLM-провайдеров. Всё, что было доступно на скомпрометированной машине:
- API-ключи OpenAI, Anthropic, Google, DeepSeek и т.д.
- AWS Access Keys и Secret Keys
- GCP Service Account JSON
- Azure Subscription Keys
- SSH-ключи (сгенерировать новые, удалить старые из authorized_keys на всех серверах)
- Kubernetes tokens
- Database passwords
- TLS private keys
- CI/CD токены (GitHub, GitLab, CircleCI)
5. Проверить Kubernetes-кластеры
Выполните: kubectl get pods -n kube-system | grep -v "^NAME" | awk '{print $1}' | sort
Ищите незнакомые поды — атакующие разворачивали привилегированные контейнеры на каждом узле.
6. Обновить LiteLLM до безопасной версии
pip install litellm==1.82.6
BerriAI приостановили релизы до завершения аудита supply chain.
Системные выводы: как не попасть в следующий раз
Пиннинг зависимостей — не рекомендация, а требование
LiteLLM использовал Trivy без пиннинга версии. Одна строчка uses: aquasecurity/trivy-action@latest в GitHub Actions — и вся цепочка безопасности рухнула. Пинните хеши коммитов, не теги.
Централизованное управление ключами
Разбросанные .env-файлы с ключами от шести провайдеров — огромная attack surface. Один прокси-слой с единым API-ключом сокращает радиус поражения: при компрометации ротируешь один ключ вместо десяти.
Keyless-аутентификация
Облачные провайдеры давно предлагают альтернативы долгоживущим ключам:
- AWS: IAM Roles + OIDC Federation
- GCP: Workload Identity Federation
- Azure: Managed Identity
- GitHub Actions: OIDC tokens вместо секретов
Keyless-подход устраняет саму категорию атаки: нечего красть, нечего ротировать.
Мониторинг зависимостей
- pip-audit для Python.
- Dependabot / Renovate для автоматического отслеживания.
- SLSA (Supply-chain Levels for Software Artifacts) для верификации происхождения пакетов.
Разделение сред
Никогда не ставьте экспериментальные пакеты в production-окружение. Виртуальные среды (venv), Docker-контейнеры, отдельные машины для тестирования. .pth-файл в общем site-packages — это именно та ситуация, которую изоляция среды предотвращает.
Каскадный эффект
Эта атака — не про LiteLLM как таковой. Это про модель, когда одна скомпрометированная зависимость в CI/CD-пайплайне открывает доступ к тысячам downstream-проектов. Trivy → LiteLLM → DSPy, MLflow и ещё 2000+ пакетов. Каждый из них — потенциальный вектор для следующей волны.
Андрей Карпаthy публично предупредил об атаке. BerriAI заморозили релизы. Но масштаб эксфильтрации — сотни тысяч устройств — говорит о том, что последствия будут проявляться ещё месяцами.
Проверьте свои системы. Ротируйте ключи. Пересмотрите архитектуру управления секретами. Не откладывайте.