Изследователи от Bloom Security установиха, че функцията Trusted Publishing в npm е позволявала на атакуващ да публикува нови версии на чужд пакет без необходимост от кражба на идентификационни данни. За целта нападателят е трябвало единствено да регистрира име на хранилище в GitHub, изоставено от предишния поддържащ разработката. Bloom идентифицира над 1500 npm пакета, изложени на риск по този начин, а GitHub, собственик на npm, съобщи, че е внедрил корекции за сигурност.

Уязвимост в Trusted Publishing на npm

Засегнатите пакети имат общо над 10 милиона изтегляния и над един милион месечно. Това прави средно по няколкостотин изтегляния на пакет на месец, но дори един превзет пакет е напълно достатъчен. Злонамерена версия може да съдържа postinstall скрипт — код, който npm изпълнява автоматично на всяка машина, инсталираща обновлението.

Как е протичала атаката

Функцията Trusted Publishing, общодостъпна от юли 2025 г., заменя дългосрочните токени за публикуване. Поддържащият посочва на npm кое хранилище и кой файл с работен процес (workflow) в GitHub имат право да публикуват даден пакет. Когато този работен процес се изпълни, GitHub му издава подписан токен за идентичност, а npm го заменя с временни идентификационни данни за публикуване, изтичащи след броени минути.

npm обаче е идентифицирал хранилището единствено по неговото име — низът от вида owner/repo, наричан от GitHub „slug“. GitHub също така присвоява на всяко хранилище и собственик постоянен цифров идентификатор, който се запазва при преименуване или прехвърляне, и включва двата идентификатора в токена. npm обаче не е проверявал тези числови идентификатори. Когато разработчик преименува, прехвърли или изтрие свързаното хранилище, или профилът на собственика бъде преименуван или изтрит, старият slug остава свободен. Всеки злонамерен субект можеше да създаде ново хранилище със същото име, да добави файл с работен процес със съответстващото име и да получи права за публикуване на пакет, който не притежава.

От Bloom са възпроизвели пълния цикъл на атаката с пакет и хранилища под техен контрол, публикувайки от хранилище на втора организация, което е регистрирало освободения slug. Версия, публикувана по този начин, разполага и с валидна атестация за произход (provenance attestation) — подписан запис на компилацията, сочещ към хранилището на атакуващия.

GitHub блокира повторната употреба на имена на хранилища с над 100 клонирания в седмицата преди преименуването или изтриването на профила на собственика, което защитава определени пакети. „Взехме това предвид. Всичко, което счетохме за уязвимо, се отнасяше за свободно достъпни за регистрация имена“, поясни Голан Майерс, изследовател по сигурността в Bloom Security.

Какви промени въведе GitHub

Bloom съобщи за проблема чрез програмата за докладване на уязвимости (bug bounty) на GitHub в HackerOne на 6 юни, а GitHub потвърди валидността му на 9 юни. От Bloom посочват, че последният получен отговор е бил на 8 юли, като шест последващи запитвания след това, включително искане за медиация към HackerOne, са останали без отговор.

Говорител на GitHub заяви пред Help Net Security: „Научихме за този инцидент чрез нашата bug bounty програма и предприехме действия за валидиране на доклада и предоставяне на корекции за отстраняване на уязвимостта. Непотвърдените конфигурации на Trusted Publishing вече изтичат 48 часа след създаването им и не могат да разрешават публикуване. Това ограничава риска от оказване на доверие на хранилище или име на проект с променена собственост.“

GitHub обяви промяната на 2 октомври, а документацията на npm посочва, че първото успешно публикуване чрез конфигурацията я обвързва с „неизменната идентичност“ на хранилището. В изявлението на GitHub не се уточнява дали конфигурациите, публикували преди промяната, са били обвързани със задна дата. Майерс отбелязва, че не е известно дали уязвимостта е била експлоатирана в реална среда.

Къде се намесват AI агентите

От Bloom подчертават, че агентите с изкуствен интелект за писане на код разширяват значително обхвата на подобни уязвимости. На базата на телеметрия от десетки организации се оценява, че AI агентите инсталират около 70 пакета месечно на стандартно крайно устройство и близо 350 на работни станции за разработчици, без да се броят зависимостите. Тези инсталации обикновено се извършват без проверка на самия пакет или неговия поддържащ автор.

„AI агентите променят правилата на играта — разработчиците вече не са единствените потребители на специализиран софтуер за разработка. Поради това проблеми като този оказват влияние върху всички потребители, за разлика от историческите възприятия“, подчертава Майерс.

Какво трябва да се провери

Ако поддържате пакет, използващ Trusted Publishing, изпълнете npm trust list и потвърдете, че всяко посочено хранилище все още сочи към такова под ваш контрол. Изтрийте и конфигурирайте наново всяка връзка, сочеща към преименувано или прехвърлено хранилище, и премахвайте връзката преди изтриване на хранилище.

Bloom не публикува списък с имената на засегнатите пакети, поради което потребителите на npm пакети не могат да направят директна проверка срещу списък. Те могат да верифицират дали атестацията за произход на пакета посочва точно хранилището, от което се очаква да произхожда проектът.

От Bloom допълват, че интеграцията на npm за Trusted Publishing с GitLab страда от същата уязвимост.