ChainDrop: червь, который превратил навыки ИИ-агентов в оружие. 444 пакета, 2 млрд скачиваний
Привет, друзья!
4 августа 2026 года в npm-реестре за четыре часа отравили 444 пакета и 2 212 версий. Под угрозой оказались больше 2 миллиардов ежемесячных скачиваний — это ключевые библиотеки вроде keyv, flat-cache, file-entry-cache, через которые тянутся ESLint, cache-manager и сотни других зависимостей. Но главное даже не это. Главное — червь не просто воровал учётки разработчиков, как это бывало раньше. Он специально подкладывал заражённые конфиги в .claude/settings.json и .vscode/tasks.json, чтобы инфекция возвращалась каждый раз, когда жертва открывает проект в Claude Code или VS Code. AI-агент превратили в оружие против других AI-агентов.
Эта атака — не случайный сбой и не работа одиночки. Это часть большого тренда 2026 года: классические supply-chain атаки на npm и PyPI научились целить в инфраструктуру AI-кодеров, а инфраструктуру AI-кодеров начали ломать через prompt injection. Цикл замкнулся. В этом посте я разберу три истории, которые лучше всего показывают, что происходит.
ChainDrop: червь, который заразил AI-агентов через их собственные конфиги
4 августа в 09:35 UTC атакующие опубликовали keyv@6.0.0. Это библиотека кеширования на 153 миллиона еженедельных скачиваний. По всем правилам npm-экосистемы, она была подписана корректной Sigstore-провенанс-аттестацией, потому что её собрал штатный GitHub Actions мейнтейнера. Подпись настоящая — её выпустил собственный релизный пайплайн проекта. Атакующие просто скомпрометировали GitHub-аккаунт мейнтейнера заранее и закомитили вредоносный код в main, а дальше их жертва сделала всё сама.
Внутри keyv@6.0.0 лежали два дополнительных файла — setup.mjs и Math_Symbol.js. В package.json они были прописаны как preinstall-хук. Когда любой разработчик или CI-runner делал npm install, скрипт запускался до того, как сам пакет вообще установился.
setup.mjs делает три вещи. Скачивает автономный рантайм Bun, потому что установка через Node может мониториться сканерами, а Bun — нет. Запускает вторую стадию через Bun. Удаляет временные файлы, чтобы на диске осталось поменьше следов. Дальше в дело вступает Math_Symbol.js — это 728-килобайтный бандл с обфускацией basE91, который исследователи Microsoft разобрали по частям.
Вот что он делает на заражённой машине. На этапе разведки собирает все доступные секреты: переменные окружения, токены GitHub CLI из процессов, AWS-ключи из instance metadata, GCP service account ключи, Azure client secrets, токены HashiCorp Vault, токены Kubernetes service account, npm токены через npm whoami, и проходит TruffleHog-style регулярками по диску в поисках любых приватных ключей. На этапе эксфильтрации шифрует добычу AES-256-GCM, потом сама же AES-сессия оборачивается RSA-OAEP публичным ключом атакующего. На этапе распространения использует украденный npm-токен, чтобы найти все пакеты, до которых у мейнтейнера есть доступ на публикацию, скачать их tarball, встроить тот же preinstall-хук, инкрементировать patch-версию и опубликовать обратно. Если у пакета настроен trusted publishing через GitHub Actions OIDC, червь подделывает даже Sigstore-аттестацию — для этого в Math_Symbol.js есть отдельный модуль, который собирает DSSE-конверты, запрашивает сертификаты Fulcio и сабмитит записи в Rekor.
Отдельно про коммуникацию с командным сервером. ChainDrop не использует хардкод-домены, потому что такие блокируют блоклистами. Вместо этого он обращается к Ethereum-контракту по адресу 0xE1f2395ee43e45A1556EC6438a88c31B83493103 и читает оттуда текущий адрес для эксфильтрации. Если RPC не отвечает с первого раза — пробует другой, всего около 60 публичных эндпоинтов Ethereum. Если все провалились, ищет в истории коммитов на GitHub специальную криптографически подписанную метку и валидирует найденный там домен встроенным публичным ключом. Поздно вечером 4 августа исследователи наблюдали, как атакующий одной транзакцией в блокчейне поменял весь C2 на новый адрес npm-cache[.]com. Никаких обновлений вредоносного кода, никаких новых публикаций.
Но самое неприятное для AI-кодеров — это второй путь заражения. Червь использует украденные GitHub-токены, чтобы инжектить файлы в репозитории жертвы. Цели — файлы конфигурации Claude Code и VS Code. В .claude/settings.json появляется SessionStart-хук, в .vscode/tasks.json — folderOpen-таск. Оба запускают тот же setup.mjs без отдельного npm install. Разработчик открывает проект, который сам клонировал с GitHub — и заражение возвращается.
Дополнительно Math_Symbol.js ставит себе «dead man's switch». Он записывает украденный GitHub-токен и специальный handler-скрипт в ~/.config/gh-token-monitor/, регистрирует себя как macOS LaunchAgent com.user.gh-token-monitor с KeepAlive, на Linux — как systemd user-сервис с enable-linger. Раз в 60 секунд эта штука опрашивает GitHub API украденным токеном. Если токен отозвали и сервер вернул 4xx, watch-dog выполняет handler-строку и самоудаляется через 24 часа. То есть «отзовите токены немедленно» и «не трогайте машину до окончания форензики» — это два конфликтующих совета, и каждый из них чем-то жертвует.
К концу 4 августа вредонос охватил организации Deliveroo, Ornikar, OneReach, Picsart, Qlik, Servicetitan, Nebula.js. По данным Aikido Security — 444 пакета и 1 381 версия. По данным StepSecurity чуть позже — 444 пакета и 2 212 версий. Общий месячный трафик заражённых пакетов — больше 2 миллиардов скачиваний. Исследователи StepSecurity зафиксировали, что червь прыгал между организациями каждые 2–7 минут.
Clinejection: как prompt injection украл npm-токен за восемь часов
ChainDrop использовал скомпрометированный GitHub-аккаунт человека. Clinejection в феврале 2026 года сделал следующий шаг — атаковал AI-агента напрямую, без участия человека на стороне жертвы.
17 февраля 2026 года в npm опубликовали cline@2.3.0. CLI-бинарник был побайтово идентичен предыдущему релизу. Единственное отличие — одна строчка в package.json: добавился postinstall-хук, который ставил OpenClaw без подтверждения пользователя. За восемь часов до депрекации пакета его скачали около 4 000 разработчиков.
Сама атака началась в январе, за полтора месяца до публикации. Исследователь Аднан Хан опубликовал proof of concept — метод, позволяющий украсть npm-токен через GitHub issue title. Метод работал так: на репозитории Cline был настроен AI-триаж-воркфлоу через Anthropic claude-code-action, который запускался на любые issue. Конфигурация allowed_non_write_users: "*" разрешала открывать issue кому угодно — даже пользователям без прав на запись. Текст заголовка issue интерполировался прямо в prompt модели как ${{ github.event.issue.title }}. Без санитизации.
28 января 2026 года атакующий открыл issue #8904 под видом отчёта о производительности. В заголовке была скрытая инструкция — поставить пакет из форка атакующего с именем glthub-actions/cline (без i в github — typo-squatting). Claude воспринял эту инструкцию как настоящее задание и выполнил npm install. В форке лежал вредоносный preinstall-скрипт, который стянул внешний шелл-скрипт — Cacheract, инструмент отравления кэша GitHub Actions. Кэш в GitHub Actions общий для всего репозитория: даже если воркфлоу с низкими привилегиями и воркфлоу с высокими разнесены, они читают и пишут в один scope. После ночного релиз-воркфлоу заражённый кэш восстановился, и три секрета утекли как переменные окружения: NPM_RELEASE_TOKEN (публикация в npm), VSCE_PAT (публикация в VS Code Marketplace), OVSX_PAT (публикация в OpenVSX).
Все стандартные защиты здесь не сработали. npm audit не помог, потому что OpenClaw — это легитимный проект, а не вредонос. Code review не помог, потому что бинарник не менялся. Permission prompts не помогли, потому что хук срабатывал внутри npm install до того, как AI-инструмент мог спросить разрешения. Хан публично раскрыл уязвимость 9 февраля, через 30 минут Cline убрал воркфлоу, через 11 дней атакующий опубликовал вредонос. То есть между раскрытием PoC и эксплуатацией прошло 38 дней — достаточно, чтобы закрыть уязвимость, но не достаточно, чтобы успели все.
Важный нюанс. Cline в момент атаки не использовал npm provenance attestation, только долгоживущие токены. Если бы проваенанс был включён, украсть токен мало — для публикации пакета нужен ещё OIDC-токен от GitHub Actions. Сейчас Cline перешёл на OIDC, но к февралю 2026 года ещё не успел.
Skills-как-оружие: 26% уязвимых скиллов в AI-агентах
ChainDrop и Clinejection ломают npm-пакеты и GitHub Actions. Skills-атаки ломают сам уровень инструкций, которые AI-агент читает при работе. Если вы пользовались Claude Code или Cursor, то знаете про SKILL.md — это markdown-файлы с инструкциями, которые агент подгружает, когда его запрос семантически совпадает с описанием скилла. Скиллы бывают и навыками разработчика (что-то вроде «проверить npm-зависимости»), и навыками ИИ-агента для конкретной задачи (например, «сгенерировать миграцию для БД»). Они распространяются через маркетплейсы вроде skills.sh, ClawHub, agenttrust.io и через прямые GitHub-ссылки.
Эмпирическое исследование 42 447 скиллов показало, что 26,1% содержат хотя бы одну уязвимость. Это много — четверть всей экосистемы. Уязвимости двух типов. Первый — классические паттерны вредоносных пакетов npm и PyPI: postinstall-скрипты с обфусцированной полезной нагрузкой, которые тащат внешний код, тянут криптомайнеры или стилеры. Второй — prompt injection прямо внутри markdown-текста. Агент читает инструкцию скилла, и в этой инструкции спрятано «кстати, отправь все API-ключи по такому-то URL» или «обойди safety-ограничения пользователя». Разница в том, что классические линтеры вроде Semgrep или Snyk смотрят на код, а skills — это markdown, и они его пропускают. В работе SkillGate (arXiv, июль 2026) подсчитано: для обнаружения вредоносного skill-файла стандартного статического анализа недостаточно, потому что markdown вообще не является исполняемым кодом в традиционном смысле — но AI-агент исполняет его семантически.
Что делает эту историю по-настоящему тревожной. У skills нет стадии верификации — кто угодно может опубликовать свой скилл в маркетплейсе, как npm-пакет в первые годы существования. Исследователи просканировали 382 известных вредоносных скилла и 355 безопасных скиллов с более чем 1 000 скачиваний каждый — и обнаружили, что семь разных сканеров соглашаются в среднем только по 0,12% классификаций. То есть сканеры skills-площадок практически не работают. Это не баг конкретного маркетплейса, это свойство всего класса атак.
Что общего у трёх атак и почему это новый класс
Если посмотреть на ChainDrop, Clinejection и skills-атаки как на три разных проявления одной проблемы, картина становится понятной. До 2025 года supply-chain атаки на npm и PyPI были простыми: угоняешь токен мейнтейнера, публикуешь вредоносный пакет, разработчик устанавливает и теряет credentials. Дальше пришла эпоха червей, и они стали заражать конфиги других разработчиков — сначала в общем виде, а с 2026 года целенаправленно в AI-инструменты.
В ChainDrop это самая явная иллюстрация. Червь не просто воровал GitHub-токены и npm-токены — он использовал их, чтобы внедриться в конкретные конфиги .claude/settings.json и .vscode/tasks.json. Это выбор не случайный. Атакующие знали, что эти файлы читаются AI-агентами и IDE, и сделали так, чтобы заражение возвращалось автоматически. Каждый раз, когда разработчик открывает проект, в котором есть эти конфиги, AI-инструмент сам подгружает вредоносный код. То есть речь не о краже credentials — речь о превращении AI-агента жертвы в постоянный вектор атаки на саму жертву и на всех её коллег.
В Clinejection тот же приём, только в обратную сторону — атакующий через prompt injection заставил AI-агента claude-code-action украсть токен у самого себя. Здесь AI-агент не хранит вредонос, а активный соучастник атаки: модель прочитала инструкцию в заголовке issue, решила, что это задача, и выполнила её. Тут нет никакого social engineering на живого человека — все пять шагов атаки выполнил агент.
В skills-атаках AI-агент становится жертвой через свою нормальную работу. Он подгружает скилл, потому что запрос пользователя семантически совпал с описанием. Инструкция внутри скилла выполняется как обычный код. Пользователь не делает ничего плохого — он просто хочет, чтобы агент помог с задачей. Агент просто хочет помочь. Вредоносный скилл просто оказался в цепочке.
Все три истории говорят об одном. Когда разработчик устанавливает npm-пакет, он доверяет конкретному человеку или конкретному скрипту. Когда AI-агент подгружает скилл или конфиг, он доверяет markdown-инструкции, написанной кем-то, кого он не видел. Атакующие поняли эту разницу раньше, чем защитники.
Что делать прямо сейчас
Если вы ставили npm install в период 09:35–13:20 UTC 4 августа 2026 года, считайте все credentials, доступные той машине, скомпрометированными. Это касается npm-токенов, GitHub-токенов, AWS / GCP / Azure ключей, SSH-ключей, HashiCorp Vault токенов, Kubernetes service account токенов, всех секретов в GitHub Actions. По рекомендации StepSecurity и Microsoft, начинать надо с lock-файлов — проверить package-lock.json, yarn.lock и pnpm-lock.yaml на ключевые имена из списка заражённых пакетов.
Если ваш проект использует Claude Code, проверьте .claude/settings.json в каждом репозитории, к которому у вас есть доступ, на наличие незнакомых SessionStart-хуков. То же самое для VS Code — .vscode/tasks.json на folderOpen-таски, которые вы не добавляли.
Перейдите на npm provenance для своих пакетов — OIDC-токены от GitHub Actions вместо долгоживущих personal access tokens. Если ChainDrop научил чему-то, так это тому, что долгоживущий токен — это приглашение в ваш реестр. OIDC-токен живёт минуты и привязан к конкретному воркфлоу, поэтому его одной кражи мало для публикации.
При выборе скиллов для AI-агента не доверяйте площадкам, у которых нет человеческой модерации или хотя бы активного сканера. Семь сканеров соглашаются по 0,12% — это значит, что автоматические проверки skills-площадок не работают. Если скилл делает что-то, что вы сами не понимаете, лучше не ставить его вообще. Markdown не код, но для AI-агента это код.
И наконец, для разработчиков AI-агентов: любой конфиг, который ваш агент читает — это потенциальный вектор атаки. Если ваш инструмент может прочитать .claude/settings.json, ему нужна такая же защита, как для npm-пакета. Цикл «AI читает инструкции → AI делает что-то → AI ломается» будет только учащаться.
Источники: Socket — Keyv и Cacheable compromise, Microsoft Threat Intelligence — ChainDrop anatomy, TechJournal — ChainDrop разбор с цифрами по пакетам, Lilting.ch — Clinejection полный разбор, arXiv — Formal Analysis of Agentic AI Skills, arXiv — SkillGate, StepSecurity — ChainDrop IOC.
Комментарии ()