Зависимости AI-проекта чаще всего становятся дырой в безопасности не потому, что кто-то написал плохой код, а потому что их вообще не проверяли. Каждый npm install или pip install затягивает в проект чужие библиотеки без единой проверки, а когда пакет предлагает AI-агент, риск удваивается: модель способна назвать библиотеку, которой вообще не существует. Ниже пошагово: как запустить npm audit и pip-audit, зачем коммитить lockfile, на что смотреть перед установкой нового пакета и как встроить это все в CI/CD перед деплоем.
Проверка зависимостей AI-проекта строится на трех слоях: npm audit или pip-audit против известных уязвимостей, lockfile в git для воспроизводимой сборки и ручная проверка downloads с датой публикации для новых пакетов. Отдельная угроза 2026 года — slopsquatting, когда AI сам придумывает несуществующий пакет, а атакующие регистрируют его заранее.
Почему зависимости AI-проекта стали главной дырой в безопасности?
Атаки идут не через ваш код, а через сторонние библиотеки в package.json или requirements.txt, которые никто вручную не читал.
Более 90% уязвимостей в npm-пакетах закрываются патчем еще до публикации CVE. У мейнтейнера есть grace period в 60-90 дней на тихий фикс до того, как проблема станет публичной. Дыра почти всегда не в отсутствии патча, а в том, что команда не обновилась вовремя.

Типичный вайбкодерский проект на Next.js или FastAPI тянет за собой сотни транзитивных зависимостей, о которых разработчик даже не подозревает. Windsurf или Cursor поставили react-scripts, а react-scripts потащил webpack-плагин, а тот, в свою очередь, библиотеку с уязвимостью remote code execution. Ни один человек этот путь глазами не проходит.
Раньше это было проблемой энтерпрайза с большими командами безопасности. Сейчас один человек за вечер собирает продукт с помощью AI и тащит в прод десятки пакетов, ни один из которых не выбирал осознанно. Аудит зависимостей перестал быть опцией для «серьезных» команд, это базовая гигиена перед любым деплоем.
Что такое slopsquatting и как ИИ подставляет вас под удар?
Slopsquatting — атака, при которой AI-модель придумывает несуществующее имя пакета, а злоумышленник заранее регистрирует его на npm или PyPI с вредоносным кодом внутри.
В январе 2026 исследователь Aikido Security обнаружил, что несуществующий npm-пакет react-codeshift распространялся по 237 репозиториям через AI-сгенерированные файлы навыков агентов. Пакет появился как галлюцинация из смешения двух реальных библиотек, jscodeshift и react-codemod, и никто изначально его не регистрировал.

Механика простая. Модель уверенно называет пакет, которого нет, и делает это предсказуемо: одно из исследований показало совпадение галлюцинированного имени в 85% повторных запросов для установки репозиториев и в 100% для установки скиллов агентов. Атакующему достаточно один раз зарегистрировать это имя и подождать, пока следующий агент попробует его установить.
Опенсорсные модели галлюцинируют чаще коммерческих, разброс по разным исследованиям от единиц до трети запросов, но даже лучшие модели не дают нулевую вероятность. Есть и обратная путаница: часть имен, придуманных для Python, реально существует на npm, поэтому разработчик может по ошибке поставить пакет из чужой экосистемы. Пакет unused-imports, замаскированный под легитимный eslint-plugin-unused-imports, в феврале 2026 все еще собирал около 233 загрузок в неделю, несмотря на то что npm пометил его как заблокированный.
Инструменты вроде Cursor, Windsurf и Claude Code участвовали в тестах именно на эту уязвимость: агент, который сам ставит зависимости, должен проверять их имя перед установкой, а не после. Подробный разбор механики есть в исследовании Cloud Security Alliance.
Зачем нужен lockfile и почему его нельзя игнорировать?
Lockfile фиксирует точные версии всех зависимостей, включая транзитивные, и без него сборка на разных машинах превращается в лотерею.
package-lock.json или pnpm-lock.yaml гарантируют идентичную установку у всех разработчиков и в CI. Команда npm ci требует наличия lockfile и падает при малейшем расхождении с package.json, поэтому она строже, чем npm install, и лучше подходит для автоматизированных сборок.

package.json описывает диапазоны версий через семантическое версионирование, а не точные номера. Значит на вашей машине могло стоять 3.2.1, а на сервере через месяц подтянется 3.4.0 с уже другим поведением или новой уязвимостью. Lockfile закрывает эту дыру: он фиксирует ровно то дерево зависимостей, которое вы тестировали.
Коммитьте package-lock.json, yarn.lock, pnpm-lock.yaml или poetry.lock в git всегда, даже в приватном репозитории. В CI и на проде используйте npm ci, а не npm install, это остановит сборку, если кто-то поменял package.json и забыл обновить lockfile. Обновления версий делайте осознанно, отдельным коммитом, а не как побочный эффект случайной установки нового пакета.
Как запустить npm audit и разобраться в отчете?
npm audit сканирует установленные зависимости и делит уязвимости на four уровня: low, moderate, high, critical.
Команда npm audit fix закрывает только безопасные, минорные обновления. Для критичных проблем, требующих смены мажорной версии, npm честно предупреждает о риске breaking changes и просит подтверждения вручную.
Разберем на реальном примере. Проект на react-scripts 3.4.1 показывает четыре уязвимости: две high и две low. Причина high-угрозы, remote code execution, сидит не в react-scripts напрямую, а в пакете serialize-javascript, до которого путь идет через встроенный webpack-плагин. npm сам предлагает решение, обновить react-scripts до 4.0.1, но предупреждает о возможных breaking changes из-за смены мажорной версии по семантическому версионированию.
Здесь работает правило: не гонитесь исправить все разом. Обновляйте по одной уязвимости, тестируйте приложение после каждого шага. И никогда не запускайте npm audit fix --force бездумно, эта команда насильно подтягивает мажорные версии, даже если это ломает продакшен. Если npm пишет «needs manual review», значит автоматика не может принять решение сама, как в случае с node-fetch внутри react-google-maps: там речь о риске DDoS, и решение нужно принимать вам, глядя на реальный контекст использования пакета.
Как проверить Python-зависимости через pip-audit?
pip-audit сравнивает установленные пакеты с базой PyPA Advisory Database и OSV, а флаг --fix умеет сам поднимать версии до безопасных.
Инструмент поддерживается Trail of Bits при участии Google, работает через PyPI JSON API и умеет выгружать SBOM в формате CycloneDX. При этом он честно предупреждает: это не статический анализатор кода, он читает дерево зависимостей, а не поведение пакета при выполнении.

Запуск простой: pip install pip-audit, затем pip-audit -r requirements.txt для файла зависимостей или просто pip-audit для текущего окружения. Инструмент не ловит уязвимости в системных библиотеках, к которым Python-пакет обращается косвенно, и он прямым текстом пишет, что не защищает от вредоносных пакетов как таковых, только от известных CVE.
База обновляется постоянно, поэтому разовый прогон перед релизом не спасает. Добавьте pip-audit как pre-commit хук и отдельным шагом в CI, который валит сборку при находке. Для параноидального уровня используйте хешированные requirements: даже если реестр PyPI скомпрометируют и подменят файл пакета, хеш не совпадет и установка остановится. Именно так в марте 2026 обнаружили компрометацию litellm, популярной прокси-библиотеки для LLM API, в рамках кампании TeamPCP.
Как проверить downloads и возраст пакета перед установкой?
Число загрузок само по себе ничего не доказывает, но вместе с датой последнего релиза и историей репозитория дает достаточно сигналов.
Пакет без reponse на GitHub, без лицензии и с последним релизом два года назад не обязательно опасен, но заслуживает паузы. Комбинация из нескольких таких флагов, а не один признак, сигнал того, что стоит поискать альтернативу.
Перед установкой нового, незнакомого пакета откройте его страницу на npmjs.com или pypi.org и посмотрите три вещи. Дату последнего релиза: если она старше года для активно развивающейся библиотеки, спросите себя почему. Ссылку на репозиторий: реальный GitHub с issues, коммитами и внятным CHANGELOG говорит о живом проекте, пустой репозиторий или его отсутствие говорит об обратном. И скрипты установки в package.json, конкретно preinstall, install и postinstall, которые выполняются автоматически на вашей машине без единого клика подтверждения.

| Что проверить | Хороший знак | Красный флаг |
|---|---|---|
| Дата последнего релиза | Регулярный цикл, 1-3 месяца для активной библиотеки | Резкий всплеск активности после долгого затишья |
| Repository | Реальный GitHub, issues и осмысленные коммиты | Ссылка отсутствует или ведет в никуда |
| postinstall-скрипт | Отсутствует или понятен по назначению | Скачивает бинарники с непонятного домена |
| Downloads | Стабильный рост, соответствует популярности задачи | Резкий скачок за неделю без видимой причины |
| Имя пакета | Точно совпадает с официальным | Похоже на реальный, но с опечаткой или лишним словом |
Как встроить проверку зависимостей в CI/CD перед деплоем?
Проверка зависимостей работает только как обязательный шаг сборки, который останавливает деплой, а не как разовая ручная процедура раз в квартал.
В npm CLI появился флаг minimum-release-age: он заставляет ждать заданное число дней перед установкой свежей версии пакета. Это прямая защита от атак, где вредоносную версию публикуют, ждут установок и быстро удаляют до того, как кто-то заметит.
Добавьте npm audit или pip-audit отдельным шагом в pipeline, который валит билд при high или critical находке. Используйте --ignore-scripts при установке в CI, чтобы postinstall-скрипты незнакомых пакетов не выполнялись автоматически. Зафиксируйте minimum-release-age на несколько дней для некритичных обновлений, разработчику это стоит пары дней ожидания, а атакующему обнуляет окно для быстрой публикации и удаления вредоносной версии. И держите отдельное расписание, ежедневный или еженедельный прогон аудита вне деплоя, потому что базы уязвимостей обновляются постоянно, а CVE публикуются с задержкой в 24-72 часа после самой атаки.

Для задач по автоматизации таких проверок в команде подойдет отдельный агент DevOps из каталога VibeCoderz, если хочется делегировать рутину, а не держать ее в голове.

| Инструмент | Что проверяет | Экосистема | Когда использовать |
|---|---|---|---|
| npm audit | Известные CVE в package.json | Node.js | Быстрая проверка перед коммитом |
| pip-audit | Известные CVE через PyPA + OSV | Python | requirements.txt, CI, pre-commit |
| Socket / Snyk Advisor | Поведение пакета, репутация, лицензии | Мультиэкосистемно | Глубокий разбор перед добавлением новой зависимости |
| cargo audit / bundler-audit | Известные CVE | Rust / Ruby | Аналог npm audit для других языков |
Аудит зависимостей: что он ловит, а что пропускает?
npm audit и pip-audit ловят уже известные, задокументированные уязвимости почти мгновенно, но бессильны против новой атаки, у которой еще нет записи в базе.
Сильная сторона обоих инструментов, скорость и нулевая стоимость: команда встроена в пакетный менеджер, отчет приходит за секунды, а автоматический fix закрывает большинство несложных случаев без единой правки кода руками.
Слабое место честнее обсудить прямо. Аудит смотрит на номер версии, а не на поведение кода, поэтому свежескомпрометированный пакет без опубликованного CVE пройдет проверку чисто. Он не остановит slopsquatting, потому что галлюцинированное имя это не уязвимая версия, а вообще другой, новый пакет, у которого просто нет истории. И он не заменяет ручной просмотр install-скриптов у пакетов с малым числом загрузок, здесь нужен человек, который откроет исходники хотя бы по диагонали.
Максим: «GoBanana мы собрали за 6-8 часов после выхода новой модели, и это принесло 12 миллионов рублей выручки без рубля рекламы. Но перед каждым деплоем все равно гоняем npm audit, даже когда хочется просто зарелизить и лечь спать. Одна дыра в зависимости обнуляет всю эту скорость.»
Итог: что проверять перед каждым деплоем AI-проекта
Соберите чек-лист в один процесс, а не держите его в голове по частям. Ниже карта, что запускать на каждом этапе.
| Этап | Действие | Инструмент |
|---|---|---|
| Перед установкой нового пакета | Проверить имя, дату релиза, репозиторий | npm view, страница пакета на npmjs.com/pypi.org |
| После установки | Прогнать аудит на известные CVE | npm audit, pip-audit |
| В git | Закоммитить lockfile | package-lock.json, poetry.lock |
| В CI/CD | Валить сборку при high/critical | npm audit --audit-level=high, pip-audit -r |
| Перед деплоем | Использовать чистую установку по lockfile | npm ci |
| На постоянной основе | Плановый прогон вне релизного цикла | cron, GitHub Action по расписанию |
Ни один из этих шагов не занимает больше пяти минут по отдельности. Вместе они закрывают и старую проблему забытых обновлений, и новую, специфичную для 2026 года, когда AI-агент сам выбирает, что установить в ваш проект.
Глоссарий
Lockfile — файл вроде package-lock.json или poetry.lock, который фиксирует точные версии всех зависимостей, включая транзитивные, для воспроизводимой сборки.
npm audit — встроенная команда npm, сравнивающая установленные пакеты с базой известных уязвимостей и выдающая отчет по уровням серьезности.
pip-audit — инструмент для Python, сверяющий зависимости с Python Packaging Advisory Database и базой OSV.
CVE — публичный идентификатор известной уязвимости в конкретном программном продукте.
Slopsquatting — атака, при которой злоумышленник регистрирует пакет с именем, которое AI-модели склонны галлюцинировать при генерации кода.
Supply chain attack — атака через компрометацию одного из звеньев цепочки поставки кода, например через захват аккаунта мейнтейнера легитимного пакета.
Транзитивная зависимость — пакет, который устанавливается не напрямую вами, а как зависимость другого пакета из вашего списка.
Частые вопросы про проверку зависимостей AI-проекта
Обязательно ли коммитить lockfile в приватный репозиторий? Да, всегда. Приватность репозитория не влияет на то, что без lockfile сборка на разных машинах и в CI может подтянуть разные версии транзитивных пакетов.
Что делать, если npm audit fix не помогает? Значит нужен мажорный апдейт, а npm намеренно не делает такие изменения автоматически из-за риска breaking changes. Смотрите отчет вручную, обновляйте пакет по одному, тестируйте после каждого шага.
Чем pip-audit отличается от safety? pip-audit опирается на связку PyPA Advisory Database и OSV и поддерживается Trail of Bits при участии Google. Safety исторически использовала собственную базу. Разумно иногда запускать оба, базы частично не пересекаются.
Как понять, что AI сгенерировал несуществующий пакет? Проверьте имя на официальной странице npmjs.com или pypi.org до установки. Если пакета там нет, а модель уверенно предлагала его установить, это классическая галлюцинация, и устанавливать такое имя вручную рискованно из-за slopsquatting.
Нужен ли аудит зависимостей для маленького MVP? Да, особенно для него. MVP собирают быстро и часто без ревью кода, а значит без единого человеческого взгляда на список пакетов. Прогон npm audit занимает секунды и не тормозит скорость сборки.
Как часто запускать audit в CI/CD? На каждый пуш и pull request как минимум, плюс отдельное плановое расписание, ежедневное или еженедельное, потому что база уязвимостей обновляется постоянно и новая запись может появиться уже после вашего последнего коммита.
Что делать, если уязвимость сидит в глубокой транзитивной зависимости? Сначала проверьте, предлагает ли npm audit fix обновление корневого пакета, который ее тянет. Если нет, ищите альтернативную библиотеку с той же функцией или временно исключайте зависимость через overrides в package.json, пока апстрим не выпустит патч.
Проверка зависимостей это рутина на пять минут, но именно она отделяет проект, который просто быстро собрали, от того, который можно спокойно деплоить. Если нужна помощь с настройкой аудита и CI/CD для конкретного AI-проекта, загляните в каталог AI-инструментов VibeCoderz или напишите Максиму напрямую в Telegram для консультации.

Обновлено: июль 2026.