Червей за кражба на идентификационни данни в npm, който се появи за първи път в keyv@6.0.0, се разпространи извън пространствата от имена на Keyv и Cacheable, засягайки стотици пакети в множество организации на 4 август 2026 г.
SafeDep потвърди 353 компрометирани версии в 79 имена на пакети в регистъра на npm. Мониторингът на компанията оценява по-широкия отпечатък на 442 версии в 353 имена, докато Aikido по-късно докладва за най-малко 868 пакета в 1381 версии. Нито един от двата по-големи сбора не може да бъде независимо възпроизведен от пълен публичен списък към момента на приключване на репортажа.
Злонамереният релийз използва скрипт за предварително инсталиране (preinstall), за да стартира пакет за кражба на идентификационни данни в средите на разработчиците и средите за непрекъсната интеграция (CI). SafeDep и Socket твърдят, че той може да събира данни за хранилища, регистри за пакети, облачни услуги и частни ключове, след което да използва наличния достъп за публикуване в npm за заразяване на още пакети.
Хранилището на Keyv също така запазва отделни куки (hooks) за Claude Code и Visual Studio Code (VS Code), които могат да изпълнят злонамерения код, след като потребителят гласува доверие на работното пространство или разреши конфигурацията на проекта.
Socket заявява, че всяка работна станция или машина за изпълнение (runner), изпълнила засегната версия, трябва да се третира като компрометирана по отношение на идентификационните данни. SafeDep съветва екипите за реагиране първо да премахнат компонента за наблюдение на отмяната на идентификационни данни, инсталиран от зловредния код, преди да подменят изложените токени и ключове.
Отмяната задейства този компонент; първоначалната подмяна на ключове може да изпълни предоставен от атакуващия локален манипулатор. npm 12 блокира неодобрени скриптове от жизнения цикъл на зависимостите по подразбиране, но по-ранните клиенти на npm и други пътища за инсталиране, които позволяват такива скриптове, остават изложени на риск.
Първата потвърдена злонамерена версия е keyv@6.0.0. Тя добавя node setup.mjs като preinstall команда и включва setup.mjs и Math_Symbol.js в пакета, докато компилираният код на библиотеката остава непроменен.
Първият етап проверява за наличие на Bun, изтегля версия 1.3.13 от официалните релийзи на средата в GitHub, ако е необходимо, и предава управлението на компилиран пакет с размер 727 680 байта.
Анализът на зловредния код от SafeDep показва, че пакетът извлича данни за GitHub, npm, облачни среди, Vault, Kubernetes, бази данни и частни ключове. Той също така чете паметта на средите за изпълнение на GitHub Actions, инсталира инструмент за наблюдение на отмяната на токени и съдържа механизъм за публикуване в npm. Socket независимо дешифрира код за модифициране, промяна на версиите и повторно публикуване на пакети, достъпни чрез открадната npm идентичност.
Регистърът се променяше твърде бързо, за да поддържа фиксиран списък от пакети за цялата кампания, които все още са маркирани като най-нови („latest“). В 17:40 ч. индийско стандартно време (IST) на 4 август страниците на npm пакетите показаха, че по-ранни версии са възстановени като най-нови за поне девет пакета от първоначалния набор на SafeDep, включително keyv@5.6.0, flat-cache@6.1.23 и cache-manager@7.2.9.
Пълната кампания не може да бъде картографирана независимо пакет по пакет, така че проверките за уязвимост трябва да използват точни имена на пакети, разрешени версии и конфигурационни файлове (lockfiles), а не кеширан списък с текущи тагове.
Общите стойности, докладвани от SafeDep и Aikido, отчитат злонамерени артефакти на пакети, а не засегнати системи. Те определят мащаба на кампанията, но не показват колко машини са инсталирали или изпълнили злонамерения код. Определянето на излагането на риск на системно ниво изисква точната версия на зависимостта, заредена на машината, и дали нейният скрипт от жизнения цикъл е бил изпълнен.
Поради променящите се тагове, чистите свързани пакети и непълния списък, блокирането на ниво пространство от имена крие риск както от пропускане на заразени версии, така и от третиране на незасегнати версии като компрометирани.
Хранилището съдържа втори път за изпълнение. Файлът .claude/settings.json в него съдържа кука SessionStart, която извиква .vscode/setup.mjs. Файлът .vscode/tasks.json съдържа задача за настройка на средата („Environment Setup“) с параметър runOn: folderOpen, която извиква .claude/setup.mjs. Тези файлове създават път за изпълнение на злонамерения код от изтеглено хранилище, но те не се изпълняват безусловно във всяка среда по подразбиране.
VS Code блокира автоматичните задачи в несигурни работни пространства и изисква потвърждение, преди да ги разреши по подразбиране. Claude Code прилага доверието в работното пространство към настройките на проекта, предоставени от хранилището. В 17:40 ч. IST на 4 август и двата файла с куки все още присъстваха в основния клон (main). Манифестът core/keyv/package.json все още декларираше версия 6.0.0, запазваше node setup.mjs като команда за preinstall и описваше setup.mjs и Math_Symbol.js за публикуване.
Заразената версия на Keyv притежаваше валиден OpenID Connect (OIDC) и произход от Supply-chain Levels for Software Artifacts (SLSA), тъй като премина през легитимния работен процес за публикуване в GitHub Actions на проекта. Сертификатът правилно идентифицира процеса на изграждане, но не може да гарантира, че изходният код, въведен в него, е бил безопасен.
SafeDep откри същия злонамерен код под директни акаунти за публикуване в npm на други места в кампанията. Компанията заяви, че автоматизираното разпространение съвпада най-добре с времето и внезапните публикувания на цели пространства от имена, въпреки че иницииращата функция не беше възстановена.
Доказателствата не показват дали червеят се е разпространил единствено от една открадната идентичност за публикуване или е включвал и отделно компрометирани идентификационни данни на издатели. Поради това масовото публикуване на пакети не може да установи колко акаунта са били компрометирани.