Безпека
Атаки на ланцюг постачання npm і ваш сайт
Що таке атака на ланцюг постачання npm, як недавні інциденти зачіпали звичайні сайти і які налаштування збірки ми ставимо на кожен Next.js-проєкт.
- Опубліковано
- Оновлено
- хв читання
- 6 хв читання
- Автор:
- Редакція Kyvrel

Атака на ланцюг постачання npm - це коли хтось підкладає шкідливий код у пакет, який встановлює ваш сайт. Ви самі цього коду не бачите: його підтягує збірка, а далі він може красти ключі або виконуватися в браузерах відвідувачів. Навіть простий корпоративний сайт тягне сотні пакетів, тож ризик стосується і вас.
У цій статті пояснюємо, як такі атаки доходять до звичайних сайтів компаній, що спільного мали недавні інциденти і які конкретні налаштування ми вмикаємо на кожній збірці. Текст для засновників і маркетологів, але з подробицями, корисними тому, хто підтримує ваш код.
Що таке атака на ланцюг постачання npm?
npm - публічний реєстр, від якого залежить майже кожен JavaScript-проєкт. Сучасний маркетинговий сайт на Next.js має кілька десятків прямих залежностей. У кожної з них свої залежності, тож реальне дерево встановлення часто налічує сотні пакетів. Свідомо ваша команда обрала лише кілька з них.
Зловмиснику не треба зламувати ваші сервери. Йому достатньо одного з трьох:
- Акаунт мейнтейнера. Фішинг, повторно використаний пароль або токен, що злетів, дають змогу опублікувати нову версію довіреного пакета.
- Переконлива підробка. Пакет із назвою, що відрізняється від популярної на одну літеру, і чекає на одруківку в команді встановлення.
- Мейнтейнер, який сам зіпсував пакет. Буває рідко, але буває: власник навмисно випускає шкідливий код.
Щойно погана версія з’явилася в реєстрі, її отримує кожен проєкт, що не зафіксував точну версію. Це може бути ноутбук розробника, CI-конвеєр або продакшн-бандл.
Недавні інциденти в npm і що їх поєднує
Останні роки дали чіткий патерн. Кілька добре задокументованих випадків варто знати на ім’я.
- chalk, debug та інші базові утиліти, вересень 2025. Мейнтейнера виманили на фальшивий домен «підтримки npm». Зловмисник опублікував версії, що перехоплювали браузерні API і підміняли адреси криптогаманців. Ці пакети встановлюють мільярди разів на тиждень, хоча чисті версії повернули за кілька годин. Розбір від Endor Labs.
- Черв’як Shai-Hulud, вересень 2025. Шкідливі скрипти встановлення шукали на машинах токени npm, GitHub і хмарних сервісів. Потім крадені токени npm використовували, щоб публікувати заражені версії інших пакетів. CISA у своєму попередженні нарахувала понад 500 скомпрометованих пакетів. У листопаді 2025 року прийшла друга хвиля.
- Зміни в реєстрі. GitHub, якому належить npm, оприлюднив план безпечнішого ланцюга постачання npm: публікація лише з 2FA, короткоживучими гранулярними токенами або через trusted publishing із CI.

Спільне тут просте: потерпілі не робили очевидних помилок. Вони встановили версію пакета, яка ще вчора була нормальною. Отже, захист має працювати навіть тоді, коли назві пакета ви довіряєте.
Чому маркетинговий сайт - реальна ціль
Легко думати, що атакують лише банки й великі SaaS-платформи. Але й у маркетинговому сайті є що вкрасти:
- Секрети на етапі збірки. Токени CMS, ключі аналітики, вебхуки форм і доступи до деплою часто лежать у середовищі збірки.
- Ваші відвідувачі. Код, що потрапив у клієнтський бандл, виконується на кожному перегляді сторінки й має доступ до форм.
- Ваша репутація. Підмінена сторінка або попередження браузера на вашому домені знищує довіру, яку будували роками.
Браузерний пейлоад вересня 2025 року - гарний приклад. На сервері він нічого не робив, а чекав у JavaScript на відвідувача з криптогаманцем. Будь-який сайт, перезібраний у той проміжок, міг його роздавати.
Як ми фіксуємо залежності на кожній збірці
Екзотичні інструменти тут не потрібні. Потрібні кілька налаштувань за замовчуванням, які вмикають один раз і перевіряють автоматично. Ось що ми ставимо на кожен Next.js-проєкт.
Комітимо lockfile і встановлюємо тільки з нього
Lockfile записує точну версію і контрольну суму кожного пакета. CI має встановлювати з нього і падати, якщо він не збігається з package.json.
# pnpm
pnpm install --frozen-lockfile
# npm
npm ciЯк пояснює документація npm, npm ci відмовляється працювати, якщо lockfile і маніфест розходяться. Так тихе оновлення не прослизне під час деплою.
Блокуємо скрипти встановлення
Більшість черв’яків у цій сфері запускаються через preinstall або postinstall. pnpm 10 більше не виконує lifecycle-скрипти залежностей без дозволу. Ми тримаємо явний список тих кількох пакетів, яким потрібна нативна збірка.
# pnpm-workspace.yaml
onlyBuiltDependencies:
- sharp
- esbuildУ npm аналог - .npmrc проєкту з ignore-scripts=true і ручний крок збірки для того, що справді його потребує.
Чекаємо, перш ніж ставити свіжі версії
Більшість шкідливих версій знаходять і видаляють за години або дні. Коротка пауза означає, що ви з ними майже не зустрінетеся. pnpm додав для цього налаштування у версії 10.16, воно описане в довіднику налаштувань pnpm.
# pnpm-workspace.yaml
minimumReleaseAge: 1440 # хвилини: пропускати версії, молодші за добуКоли виходить справжнє виправлення безпеки, ми виключаємо цей один пакет і оновлюємо його свідомо.
Не пускаємо секрети в клієнтський бандл
У Next.js у браузер потрапляють лише змінні з префіксом NEXT_PUBLIC_. Ми перевіряємо цей список на старті кожного проєкту. Токени запису в CMS, адреси вебхуків і рядки підключення до бази такого префікса не отримують ніколи.
Менше залежностей, оновлення через рев’ю
Кожен пакет, який ви не встановили, - це пакет, якому не треба довіряти. Ми віддаємо перевагу можливостям платформи і невеликим власним утилітам, а не окремій бібліотеці під кожну дрібницю. Оновлення приходять окремими pull request’ами з рев’ю, а не тихо в день релізу.

Що запитати в розробника чи агенції цього тижня
Щоб оцінити ризик, читати код не обов’язково. Поставте ці запитання і зверніть увагу, чи відповіді конкретні:
- Чи lockfile у репозиторії, і чи CI встановлює через
npm ciабоpnpm install --frozen-lockfile? - Чи скрипти встановлення залежностей заблоковані за замовчуванням, із коротким списком винятків?
- Чи є затримка перед тим, як приймати щойно опубліковані версії пакетів?
- Які змінні оточення потрапляють у браузер, і хто перевіряв цей список?
- Хто отримує сповіщення, коли advisory зачіпає сайт, і як швидко реагує?
- Чи захищені акаунти npm і GitHub на проєкті через 2FA, бажано апаратними ключами?
Розмиті відповіді - уже сигнал. Гігієна залежностей стоїть поруч із базовими речами з нашого чекліста безпеки сайту: заголовки, HTTPS, контроль доступу.
Як це вписується в проєкт
Політику залежностей ми вважаємо частиною збірки, а не аудитом «на потім». Її налаштовуємо в перший тиждень, записуємо в репозиторій і перевіряємо в CI. Те саме стосується вибору стеку з нашого огляду маркетингового сайту на Next.js: що менше рухомих частин, то легше тримати сайт у безпеці.
Безпеку видно і в тому, як ми передаємо проєкт. Ви отримуєте репозиторій, конфігурацію CI і коротку нотатку про кожне налаштування. Якщо згодом сайт підхопить інша команда, вона успадкує не лише код, а й запобіжники. Де саме це відбувається, видно в нашому процесі роботи.
Сплануйте безпечнішу збірку свого сайту
Якщо ваш сайт залежить від npm-пакетів, а так майже напевно і є, ці налаштування варто мати до наступного інциденту. Ми вмикаємо їх стандартно в кожному нашому проєкті, зокрема в розробці веб-застосунків: MVP коштує від 25 000 $ і зазвичай займає 12-16 тижнів. А відповідь на питання скільки коштує сайт ми публікуємо відкрито, з кожною додатковою опцією окремим рядком.