Компрометация пакетов LiteLLM в PyPI затронула не только код самой библиотеки, но и среду, куда она устанавливается. В отдельных вредоносных wheel-сборках присутствовали файлы, которые Python обрабатывает при инициализации интерпретатора. Поэтому полезная нагрузка могла запускаться без импорта LiteLLM приложением. Для проектов, использующих библиотеку как единый шлюз к LLM-провайдерам, это означает риск утечки ключей AI-сервисов, облачных учётных данных и других секретов из рабочего окружения.

Почему импорт не был условием запуска.

Ключевым механизмом стал файл с расширением.pth, размещённый в каталоге site-packages. Обычно такие файлы применяют для настройки путей поиска модулей. Однако строки, начинающиеся с import, исполняются Python при обычной инициализации среды. Как описано в разборе CodeScoring, строка import cook в файле cook.pth загружала модуль cook ещё до логики пользовательского приложения.

Этот способ меняет модель анализа угроз. Проверка, достижим ли подозрительный участок кода через импорты конкретного приложения, здесь не даёт полного ответа: точка входа находится не в библиотеке, а в настройках запуска интерпретатора. По данным исследования JFrog Security Research, второй механизм использовал файл sitecustomize.py. Python автоматически пытается импортировать такой модуль после настройки путей, поэтому он тоже может выполняться при запуске среды.

Какие версии и артефакты фигурируют в сообщениях.

В представленной фактуре описаны две группы скомпрометированных релизов. Публикации о версиях 1.82.7 и 1.82.8 указывают, что в первом случае вредоносная логика была связана с импортом функциональности прокси, а во втором появился.pth-файл, расширивший запуск на каждый старт Python. Технический анализ Securelist сообщает, что в обоих вариантах применялся зашифрованный base64-код: после запуска он сохранялся рядом со скриптом как p.py и исполнялся.

Отдельно источники описывают вредоносные wheel-пакеты LiteLLM версии 1.107.0. По сведениям ITZine, дополнительные файлы cook.pth, cook.py и sitecustomize.py находились во всех семи установочных пакетах этой версии и были доступны в PyPI ограниченное время. Сведения о 1.82.7, 1.82.8 и 1.107.0 не следует автоматически сводить к одному и тому же релизу или одной технике доставки: общим для них остаётся использование опубликованного пакета как точки проникновения.

Сравнение исходного кода и поставляемого артефакта в данном случае принципиально. В сообщениях о ранних версиях подчёркивается, что вредоносного фрагмента не было в официальном GitHub-репозитории, а проблема находилась в опубликованных пакетах PyPI. Для 1.107.0 исследователи JFrog также указывают: в source distribution дополнительных файлов не было, тогда как wheel содержал их в структуре, устанавливаемой в корень site-packages. Это значит, что аудит репозитория без проверки конкретных скачанных wheel-файлов мог не обнаружить компрометацию.

На какие данные рассчитывали атакующие.

LiteLLM используется как SDK и прокси, объединяющий доступ к моделям разных поставщиков. Поэтому процессы с этой библиотекой нередко имеют ключи провайдеров, параметры подключения к базам данных, облачные идентификаторы и конфигурацию прокси. По данным Anti-Malware.ru, код в заражённых пакетах собирал данные, шифровал их и отправлял на инфраструктуру атакующих, маскируемую под домены, похожие на легитимные.

Анализ версии 1.107.0 расширяет картину целей. Как следует из отчёта Endor Labs, отдельный компонент обращался к таблицам LiteLLM_CredentialsTable и LiteLLM_ProxyModelTable, где прокси может хранить учётные данные провайдеров и настройки моделей. Другие описанные цели включали переменные окружения,.env-файлы, закрытые SSH-ключи, секреты Kubernetes и систем сборки, а также сохранённые данные браузеров.

Опасность не исчерпывалась кражей данных. В материалах о 1.107.0 говорится о фоновом загрузчике, который периодически проверял внешний указатель на GitHub и мог получать код для выполнения. Это превращает единичную установку вредоносного артефакта в потенциальный канал дальнейшего управления средой. При этом сам факт наличия загрузчика не означает, что дополнительная команда была получена или выполнена на каждой затронутой машине.

Что меняется в защите цепочки поставки.

Инцидент показывает ограниченность подхода, при котором доверие строится только на названии пакета, версии в зависимостях и ревизии исходного репозитория. Для Python важны также формат артефакта, список файлов в wheel и механизмы, автоматически вызываемые интерпретатором. Особого внимания требуют.pth, sitecustomize.py, usercustomize.py и необычные данные, устанавливаемые рядом с пакетами.

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