Slopsquatting и package hallucinations на практике: как не установить вредоносный пакет по совету ИИ
Defensive-разбор для команд, которые используют AI-кодинг: как перепроверять install-команды, имена пакетов и сигналы сомнительной зависимости
Зачем это важно прямо сейчас
Когда разработчик просит ChatGPT или Copilot написать кусок кода с зависимостями, он обычно доверяет результату. Имена пакетов в сгенерированном коде выглядят убедительно: они следуют соглашениям об именовании, похожи на настоящие библиотеки. Именно это делает слабость неочевидной.
В апреле 2025 года Сет Ларсон, Developer-in-Residence Фонда Python, ввёл термин slopsquatting — портмантo из «AI slop» (низкокачественный вывод ИИ) и «typosquatting» (регистрация ошибочно написанных имён) [1]. Механизм проще, чем кажется: LLM выдаёт несуществующее имя пакета, злоумышленник регистрирует его с вредоносной нагрузкой — и теперь каждый, кто получит тот же ответ от той же модели, установит малварь.
Для CTO и Tech Lead важен масштаб. Академическое исследование USENIX Security 2025, которое уже получило награду за лучшую статью конференции, показало: из 576 000 сгенерированных образцов кода на Python и JavaScript каждый пятый содержал несуществующее имя пакета [2]. Это не единичные случаи — это системная особенность того, как работают языковые модели при генерации кода.
Что такое package hallucination и почему это происходит
LLM не «знает» содержимое npm или PyPI в реальном времени. Модель обучена на огромном корпусе текстов, включая документацию, README-файлы, туториалы и форумы. Когда ей нужно предложить зависимость, она генерирует статистически правдоподобное имя — то, которое «похоже» на то, что встречалось в обучающих данных. Если такого пакета нет в реестре, это называется hallucination.
Исследователи из Университета Техаса в Сан-Антонио и Виргинского политехнического института протестировали 16 популярных LLM для генерации кода на двух наборах промптов [3]. Ключевые находки:
- Коммерческие модели галлюцинируют в среднем в 5,2% случаев; GPT-4 Turbo — лучший результат в группе, около 3,59%.
- Модели с открытым кодом галлюцинируют в 21,7% случаев. CodeLlama 7B и CodeLlama 34B — в более чем трети выводов.
- Всего в эксперименте было зафиксировано 205 474 уникальных выдуманных имени пакетов.
- В разговорном режиме (conversational settings) Gemini демонстрировал hallucination в 64,5% сессий — данные Lasso Security [4].
Особенно важна находка о повторяемости: при десятикратном запуске одного и того же промпта 43% выдуманных имён появлялись в каждом из десяти прогонов [5]. Это означает, что злоумышленник может систематически зондировать модели, выявлять стабильно галлюцинируемые имена и занимать их на PyPI или npm заблаговременно.
Дополнительный риск — кросс-экосистемная путаница: 8,7% выдуманных Python-пакетов оказались настоящими npm-пакетами. Модели иногда перепутывают экосистемы, предлагая JavaScript-пакет в Python-контексте — и это тоже эксплуатируемое поведение [5].
Slopsquatting vs. typosquatting: в чём разница и почему это хуже

Typosquatting существует с 2017 года, когда в npm появился crossenv — сквот популярного cross-env [4]. Реестры со временем ввели защиту от имён, слишком похожих на существующие популярные пакеты.
Slopsquatting обходит эту защиту, потому что выдуманные имена зачастую вообще не похожи ни на что существующее — они просто правдоподобны синтаксически и семантически. Сравним:
- Typosquatting:
reqeustвместоrequest— человек опечатался. - Slopsquatting:
aws-helper-sdkилиfastapi-middleware— имя, которое придумала модель.
У атакующего несколько ключевых преимуществ по сравнению с классическим typosquatting:
- Объём потенциальных целей на несколько порядков выше: только в одном исследовании зафиксировано более 205 тысяч уникальных галлюцинированных имён.
- Атака масштабируется через самих пользователей: чем популярнее модель и промпт, тем больше людей получат одинаково «заражённый» ответ.
- AI-агенты выполняют install-команды автоматически — без паузы, которая у человека возникает естественным образом при копипасте.
Ещё один вектор — транзитивные зависимости: выдуманное имя может попасть не в прямой import, а в зависимость зависимости. В package.json оно не появится, но установится при npm install [4].
Реальные инциденты: что уже произошло
Кейс huggingface-cli
В 2023 году исследователь Bar Lanyado из Lasso Security заметил: LLM стабильно предлагают pip install huggingface-cli, хотя настоящий пакет называется иначе и устанавливается командой pip install -U "huggingface_hub[cli]". Lanyado зарегистрировал пустой пакет под выдуманным именем. За три месяца huggingface-cli получил более 30 000 аутентичных загрузок. Alibaba скопировала галлюцинированную команду установки в README одного из своих публичных репозиториев [4]. Пакет был безобидным, но эксперимент доказал: механизм работает, и в реальных условиях его уже можно было использовать для атаки.
Пакеты GlueStack (npm, июнь 2025)
6 июня 2025 года Aikido Security обнаружила компрометацию более десятка npm-пакетов экосистемы GlueStack с суммарным недельным скачиванием около 1 миллиона. Вредоносный код был внедрён в lib/commonjs/index.js и позволял выполнять команды оболочки, делать скриншоты и эксфильтровать данные [6]. Инцидент был выявлен в течение нескольких минут после публикации.
eslint-config-prettier (npm, июль 2025)
Атакующие получили доступ к аккаунту мейнтейнера через фишинг, опубликовали заражённую версию пакета с миллионами недельных загрузок. Пакет содержал postinstall-скрипт, устанавливавший Scavenger RAT. Вредоносная версия оставалась в реестре около двух часов, но из-за популярности пакета ущерб успел распространиться [7].
num2words v0.5.15 (PyPI, июль 2025)
Подозрительная версия популярной Python-библиотеки была опубликована без соответствующего тега в GitHub-репозитории и без коммитов. Автоматизированные инструменты управления зависимостями (Dependabot) немедленно начали создавать pull request'ы с предложением обновиться [8]. Инцидент был выявлен сообществом в течение нескольких часов.
Эти случаи демонстрируют: угроза не только теоретическая. Атаки через supply chain происходят регулярно, механизмы становятся сложнее, а автоматизированные инструменты могут ускорить распространение компрометации.
Как работает типичная атака на практике
Пошаговая цепочка атаки через slopsquatting выглядит так:
- Атакующий систематически запрашивает у одной или нескольких LLM код на типичные задачи (парсинг JSON, работа с S3, HTTP-клиент, аутентификация).
- Из ответов извлекаются имена пакетов, которые модель предлагает стабильно — особенно те, которых нет в npm или PyPI.
- Атакующий регистрирует выбранные имена на публичных реестрах — для этого не нужно взламывать ничего, только создать аккаунт.
- В зарегистрированный пакет загружается вредоносный код: credential stealer, RAT, cryptominer или просто код, создающий backdoor.
- Следующий пользователь, запросивший у той же модели похожий код, получает то же имя пакета и устанавливает малварь.
Проблема в том, что шаг 5 может пройти незаметно: пакет выглядит работоспособным (атакующие всё чаще добавляют реальный функционал рядом с нагрузкой [2]), а postinstall-скрипт выполняется до того, как разработчик успевает прочитать код зависимости.
Если разработку ведёт AI-агент (Claude Code, Cursor в агентном режиме, аналогичные инструменты), ситуация усугубляется: агент выполнит npm install или pip install автоматически, без паузы для подтверждения [4].
Сигналы сомнительной зависимости: на что смотреть до install
Большинство атак через supply chain имеют выявляемые признаки — если знать, где смотреть.
Возраст пакета
Slopsquatting-пакеты всегда новые, потому что злоумышленник регистрирует их под конкретный hallucination. Пакет, которому меньше 48–72 часов, требует повышенного внимания.
Для npm:
npm view <package-name> time.created --jsonДля PyPI:
curl -s https://pypi.org/pypi/<package-name>/json | jq '.info | {name, author, home_page}'Несоответствие между реестром и GitHub
Легитимный пакет обычно имеет связанный репозиторий, историю коммитов, теги релизов. Подозрительные признаки: версия опубликована на PyPI/npm без соответствующего тега в GitHub; README минималистичен или скопирован с другого пакета; нет issue tracker; один мейнтейнер, зарегистрированный в день публикации.
Статистика загрузок
Не является надёжным сигналом сам по себе (новый пакет и должен иметь мало загрузок), но резкий скачок загрузок при отсутствии истории — повод насторожиться.
postinstall- и prepare-скрипты
Это главный вектор исполнения вредоносного кода при установке. Проверить наличие install-скриптов можно до установки:
# npm: посмотреть package.json без скачивания кода
npm view <package-name> scripts --json
# или установить с отключёнными скриптами
npm install <package-name> --ignore-scriptsДля PyPI аналог — наличие setup.py с нестандартным содержимым в секции install_requires или cmdclass.
Обфускация кода
Несколько подтверждённых случаев 2025 года использовали обфускацию с японскими Unicode-символами как именами переменных, шифрование нагрузки внутри LICENSE-файла, многоступенчатую распаковку [7]. Читаемость кода — косвенный, но реальный сигнал.
Имя в неправильной экосистеме
Если AI предлагает Python-пакет, а точно такое же имя существует только в npm — это признак кросс-экосистемной путаницы модели и потенциальная точка атаки.
Как перепроверять install-команды: практический чеклист
Перед выполнением любой команды установки из AI-подсказки или чужого README рекомендуется пройти следующие проверки.
Шаг 1. Убедитесь, что пакет существует в официальном реестре
# PyPI
pip index versions <package-name>
# или
curl -s https://pypi.org/pypi/<package-name>/json | jq .info.name
# npm
npm view <package-name>Если пакет не найден — это уже red flag. Не ищите его на GitHub вручную и не пытайтесь установить из непроверенного источника.
Шаг 2. Проверьте дату публикации и историю версий
Пакет с одной версией и датой публикации «2 часа назад» требует объяснения. Посмотрите на историю версий: у легитимных библиотек она, как правило, растянута во времени.
Шаг 3. Сверьте официальную документацию
Для популярных фреймворков и SDK (AWS, HuggingFace, FastAPI и т.д.) правильная команда установки всегда есть в официальной документации. Если AI предлагает pip install huggingface-cli, а официальный сайт показывает другую команду — верьте официальной документации.
Шаг 4. Проверьте связь пакета с репозиторием
npm view <package-name> repository --json
# или на PyPI: поле "Source" на странице пакетаНаличие живого репозитория с историей — хороший знак. Отсутствие — повод для дополнительной проверки.
Шаг 5. Проверьте install-скрипты перед установкой
npm view <package-name> scripts --jsonЕсли есть preinstall, install, postinstall — прочитайте их содержимое до установки. Для npm это возможно без скачивания кода через npm pack --dry-run.
Шаг 6. Используйте инструменты статического анализа до install
Socket.dev анализирует поведение пакетов: сетевые запросы, доступ к файловой системе, обфускацию, подозрительные паттерны в коде. В отличие от npm audit, который проверяет только известные CVE, Socket смотрит на поведение [9].
npq — обёртка для npm, которая перед установкой проверяет возраст пакета, наличие README и LICENSE, популярность, уязвимости через Snyk [10].
Aikido SafeChain — open-source обёртка для npm, npx, yarn, pnpm, pip, uv и poetry. Перехватывает команду установки, проверяет по threat intelligence feed Aikido до того, как пакет скачан [11].
Три слоя защиты для команды
Ни один из этих слоёв не является достаточным сам по себе, но в сочетании они блокируют большинство практических атак.
Слой 1. Минимальный возраст пакета (release age gate)
pnpm 11 поддерживает minPublishAge — отказ от установки любой версии пакета моложе указанного порога. В package.json:
{
"pnpm": {
"minPublishAge": "72h"
}
}Для Python с uv:
[tool.uv]
exclude-newer = "7 days"Этот слой блокирует наиболее распространённый паттерн slopsquatting: атакующий регистрирует пакет за несколько часов до того, как разработчик попытается его установить. Задержка в 72 часа отсекает большинство свежезарегистрированных вредоносных пакетов [9].
Слой 2. Изолированное окружение для install
Если AI-агент запускает install-команды автоматически, постинсталляционный скрипт должен выполняться в окружении без доступа к SSH-ключам, AWS credentials, токенам и другим секретам. Это ограничивает радиус поражения: скрипт физически не может украсть то, чего нет в среде выполнения.
На практике это означает отдельный контейнер без монтирования ~/.ssh, ~/.aws, .env и аналогичных директорий для шагов, где происходит установка зависимостей.
Слой 3. Перехват install-команды до исполнения
Aikido SafeChain и аналогичные инструменты перехватывают вызов пакетного менеджера до того, как происходит обращение к реестру. Это означает, что проверка происходит раньше, чем любой код зависимости получит шанс на выполнение [11].
Socket.dev GitHub App анализирует каждый новый или обновлённый пакет в PR и оставляет предупреждение в code review — ещё до merge [9].
Особый случай: AI-агенты и vibe-coding
Стандартные советы по безопасности зависимостей написаны для человека, который делает паузу между «AI предложил» и «я запустил install». AI-агенты эту паузу убирают.
Claude Code, Cursor в agentic-режиме и аналогичные инструменты могут выполнять npm install и pip install автоматически в рамках задачи — без дополнительного подтверждения, если настроены в режиме bypass. Slopsquatting рассчитан именно на эту модель: атакующий делает ставку на то, что агент не проверит, а просто установит [4].
Исследование Trend Micro 2025 года показало, что паттерны hallucination воспроизводятся и в agentic workflows: vibe-coding агрегирует сниппеты из GitHub README и документации разных экосистем без проверки реестра, а агент на базе Cursor иногда «склеивает» правдоподобные имена из семантических компонентов, создавая несуществующие пакеты [4].
Исследователи Unit 42 предложили SHIELD-фреймворк для агентного AI-кодинга: Separation of duties (разделение привилегий агента), Human in the loop (обязательная точка подтверждения перед install), Input/output validation [12].
Практический вывод: если AI-агент запускает install-команды автоматически в вашем pipeline, минимальный возраст пакета и перехват через SafeChain или аналог должны быть включены на уровне инфраструктуры, а не полагаться на ручную проверку разработчика.
Что не поможет и почему
npm audit и pip-audit — проверяют только известные CVE из advisory-баз. Новый malware-пакет, не попавший ни в одну базу, пройдёт эту проверку без предупреждений. Это необходимые, но недостаточные инструменты.
Ручное чтение кода зависимостей — теоретически правильный подход, практически невыполнимый при количестве транзитивных зависимостей современных проектов. npm-проект средней сложности может иметь сотни транзитивных зависимостей.
Доверие к высокому числу загрузок — при slopsquatting-атаке на популярную hallucination (типа huggingface-cli) пакет может набрать десятки тысяч загрузок за несколько месяцев [1]. Счётчик загрузок не является сигналом безопасности.
Надежда на то, что модель сама обнаружит галлюцинацию — GPT-4 Turbo и DeepSeek смогли самостоятельно выявить собственные галлюцинации с точностью около 75% [5]. Это интересный результат, но 25% необнаруженных случаев при масштабе современного AI-кодинга — по-прежнему значительная поверхность атаки.
Контроль на уровне PR и релиза
Проблема slopsquatting проявляется не только в момент npm install на рабочей машине. Она возникает каждый раз, когда новая или обновлённая зависимость попадает в codebase — в том числе через автоматические PR от Dependabot или Renovate.
Инцидент с num2words в июле 2025 года показал: Dependabot начал создавать pull request'ы с предложением обновиться до скомпрометированной версии в течение нескольких минут после публикации [8]. Если команда автоматически мержит dependency update PR, этого времени было бы достаточно для компрометации.
Для команд, использующих AI в разработке, контроль на уровне PR означает несколько вещей:
- Каждое изменение в
package.json,requirements.txt,go.modили аналогичных файлах должно проходить проверку — и не только по CVE-базам. - Новые зависимости, появившиеся в PR, сгенерированном AI-инструментом, требуют особого внимания: это именно тот контекст, в котором возникают package hallucinations.
- Транзитивные зависимости должны быть видны в review: lock-файл является частью безопасности, не техническим артефактом.
HighVibe как слой контроля до merge решает именно эту задачу: анализирует конкретные изменения в зависимостях и служебных файлах, объясняет риск простым языком и предлагает следующий шаг — исправить, перепроверить или остановить merge. Это не замена SCA или npm audit, а дополнительная точка контроля в момент, когда изменение ещё не попало в продакшн.
Что делают реестры и как это помогает
PyPI и npm предпринимают меры на уровне инфраструктуры:
- PyPI в 2024 году ввёл поддержку digital attestations — механизм верификации подлинности пакетов для мейнтейнеров [13].
- GitHub в 2025 году сократил максимальный срок действия npm-токенов с неограниченного до 90 дней, а по умолчанию — до 7 дней [9]. Это снижает окно атаки при компрометации мейнтейнерского аккаунта.
- Alpha-Omega спонсирует работу Safety and Security Engineer в PyPI для улучшения обнаружения malware и API для репортинга вредоносных пакетов [14].
Однако, как отмечает Сет Ларсон, это паллиативные меры для структурной проблемы: публичные реестры намеренно открыты и permissionless — это их ключевое свойство и одновременно то, что делает их эксплуатируемыми [14].
Тренды и открытые вопросы
Несколько направлений заслуживают наблюдения в 2025–2026 годах.
Рост агентного AI-кодинга означает рост атакуемой поверхности. Чем больше агентов работают в autonomy-режиме, тем менее значима пауза между «AI предложил» и «установлено».
Разрыв между возможностями моделей и безопасностью остаётся структурным. Veracode в исследовании GenAI Code Security Report 2025 протестировала более 100 LLM и обнаружила, что 45% задач по генерации кода привели к введению известных уязвимостей [12]. Более новые и более крупные модели не генерируют существенно более безопасный код.
Reasoning-модели снижают частоту hallucination примерно вдвое по сравнению с базовыми, но не устраняют проблему полностью — edge cases остаются даже при MCP-валидации в реальном времени [15].
Вопрос об ответственности пока открыт. Кто несёт ответственность, если AI-ассистент порекомендовал вредоносный пакет и разработчик его установил — модель, разработчик инструмента или команда? Правовых прецедентов пока нет.
Выводы и что делать дальше
Package hallucinations — это не временный баг, который «починят» в следующей версии модели. Это структурное следствие того, как LLM генерируют код, и оно будет присутствовать в любом инструменте, который не верифицирует рекомендации в реальном времени.
Slopsquatting превращает это следствие в практический вектор атаки с низким порогом входа: не нужно взламывать инфраструктуру, достаточно зарегистрировать имя в публичном реестре.
Минимальный набор действий для команды, использующей AI-кодинг:
- Включить минимальный возраст пакета на уровне конфигурации менеджера зависимостей (72 часа для npm через pnpm, 7 дней для Python через uv).
- Установить SafeChain или аналог, чтобы перехватывать install-команды до их выполнения.
- Запускать install-шаги в изолированном окружении без доступа к credentials.
- Настроить Socket.dev или аналогичный инструмент на уровне GitHub для проверки поведения новых зависимостей в PR.
- Не автоматически мержить dependency update PR без проверки — в том числе от Dependabot.
- Для AI-агентов в autonomy-режиме требовать явного подтверждения перед install-командами.
Ни один из этих шагов не требует дорогостоящей инфраструктуры. Большинство инструментов, упомянутых в этом материале, имеют бесплатный tier для открытых репозиториев.
Источники
[1] Wikipedia — "Slopsquatting" — https://en.wikipedia.org/wiki/Slopsquatting
[2] Spracklen et al., USENIX Security 2025 — "We Have a Package for You! A Comprehensive Analysis of Package Hallucinations by Code Generating LLMs" — https://www.usenix.org/conference/usenixsecurity25/presentation/spracklen
[3] arXiv preprint — "We Have a Package for You!" — https://arxiv.org/abs/2406.10279
[4] Aikido Security — "Slopsquatting: The AI Package Hallucination Attack Already Happening" — https://www.aikido.dev/blog/slopsquatting-ai-package-hallucination-attacks
[5] Socket.dev — "The Rise of Slopsquatting: How AI Hallucinations Are Fueling a New Class of Supply Chain Attacks" — https://socket.dev/blog/slopsquatting-how-ai-hallucinations-are-fueling-a-new-class-of-supply-chain-attacks
[6] TechBeams — "Npm and PyPI Ecosystems Hit By Supply Chain Malware" — https://www.techbeams.com/npm-and-pypi-ecosystems-hit-by-supply-chain-malware/
[7] The Hacker News — "Malicious PyPI and npm Packages Discovered Exploiting Dependencies in Supply Chain Attacks" — https://thehackernews.com/2025/08/malicious-pypi-and-npm-packages.html
[8] StepSecurity — "Supply Chain Security Alert: num2words PyPI Package Shows Signs of Compromise" — https://www.stepsecurity.io/blog/supply-chain-security-alert-num2words-pypi-package-shows-signs-of-compromise
[9] GitHub Gist — "Supply-Chain Attack Defense: Developer Host Machine Hardening" — https://gist.github.com/vitaliig11/9b7510c9d23c83a1b456dab56d3b3865
[10] npmjs.com — "npq" — https://npmjs.com/package/npq
[11] GitHub — "AikidoSec/safe-chain" — https://github.com/AikidoSec/safe-chain
[12] Pixelmojo — "Slopsquatting and AI Supply Chain Attacks: A Defense Guide" — https://www.pixelmojo.io/blogs/slopsquatting-ai-supply-chain-attacks-defense-guide
[13] Socket.dev npm package publish-police — PyPI Digital Attestations reference — https://socket.dev/npm/package/publish-police
[14] ThinkPol — "Slopsquatting: the supply chain attack vibe coding made" — https://thinkpol.ca/2026/03/28/slopsquatting-the-supply-chain-attack-vibe-coding-made/
[15] The Hacker News — "PyPI, npm, and AI Tools Exploited in Malware Surge Targeting DevOps" — https://thehackernews.com/2025/06/malicious-pypi-package-masquerades-as.html