Материал

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:

  1. Объём потенциальных целей на несколько порядков выше: только в одном исследовании зафиксировано более 205 тысяч уникальных галлюцинированных имён.
  2. Атака масштабируется через самих пользователей: чем популярнее модель и промпт, тем больше людей получат одинаково «заражённый» ответ.
  3. 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 выглядит так:

  1. Атакующий систематически запрашивает у одной или нескольких LLM код на типичные задачи (парсинг JSON, работа с S3, HTTP-клиент, аутентификация).
  2. Из ответов извлекаются имена пакетов, которые модель предлагает стабильно — особенно те, которых нет в npm или PyPI.
  3. Атакующий регистрирует выбранные имена на публичных реестрах — для этого не нужно взламывать ничего, только создать аккаунт.
  4. В зарегистрированный пакет загружается вредоносный код: credential stealer, RAT, cryptominer или просто код, создающий backdoor.
  5. Следующий пользователь, запросивший у той же модели похожий код, получает то же имя пакета и устанавливает малварь.

Проблема в том, что шаг 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 означает несколько вещей:

  1. Каждое изменение в package.json, requirements.txt, go.mod или аналогичных файлах должно проходить проверку — и не только по CVE-базам.
  2. Новые зависимости, появившиеся в PR, сгенерированном AI-инструментом, требуют особого внимания: это именно тот контекст, в котором возникают package hallucinations.
  3. Транзитивные зависимости должны быть видны в 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-кодинг:

  1. Включить минимальный возраст пакета на уровне конфигурации менеджера зависимостей (72 часа для npm через pnpm, 7 дней для Python через uv).
  2. Установить SafeChain или аналог, чтобы перехватывать install-команды до их выполнения.
  3. Запускать install-шаги в изолированном окружении без доступа к credentials.
  4. Настроить Socket.dev или аналогичный инструмент на уровне GitHub для проверки поведения новых зависимостей в PR.
  5. Не автоматически мержить dependency update PR без проверки — в том числе от Dependabot.
  6. Для 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

Нужен такой же контроль в ваших изменениях и релизах?

Покажем пример такого замечания на вашем сценарии и соберём пилотный контур без лишней суеты.

Запросить пилот Все статьи
Дальше по теме

Ещё материалы

Все статьи
24 июня 2026 18 мин

Политика использования ИИ в команде разработки: как не опоздать, когда всё уже идёт

Если разработчики уже пишут код с ИИ ассистентами, политика нужна сегодня — а не после первого инцидента TL;DR Более 84% разработчиков уже используют или планируют использовать ИИ инструменты 1 , и большинство делают эт…

Открыть материал
23 июня 2026 16 мин

Регистрация и онбординг пользователей: где появляются первые уязвимости

Форма регистрации выглядит просто. За ней скрывается один из наиболее атакуемых периметров приложения. TL;DR Форма регистрации и онбординг флоу — это первая поверхность атаки, которую видит злоумышленник. Большинство уя…

Открыть материал
23 июня 2026 15 мин

Бизнес-логика и мошенничество в продукте: что проверять до запуска

Ваш продукт работает правильно. Но это не значит, что он работает безопасно. TL;DR Уязвимости бизнес логики — это не сломанный код, а сломанные правила: приложение делает именно то, что написано, но не то, что задумывал…

Открыть материал