Коли npm ставить акаунт на 72 години в read-only: навіщо це захисту пакетів

npmбезпека пакетівланцюжок постачання

Розбираємо, чому 72-годинний read-only для high-impact account — це не зайва незручність, а вікно для виявлення атаки та спокійного відновлення релізного процесу

Коли реліз зупиняється через захист акаунта

Уявіть нічний інцидент: хтось змінює email на важливому npm-акаунті або використовує recovery code для 2FA, а через кілька хвилин команда бачить у CI, що npm publish більше не проходить. Реліз зависає, черга деплоїв стоїть, але це не просто поломка. npm переводить high-impact account у read-only, щоб зловмисник не встиг вивести пакет у прод зі шкідливою версією. Це головна ідея: дати команді час перевірити, хто, коли і що робив.

Чому 72 години паузи працюють саме в правильному місці

У більшості атак на ланцюжок постачання зловмисник діє швидко: отримує доступ, міняє контакти, забирає контроль на себе, публікує шкідливий артефакт і чекає, поки залежність розійдеться по чужих проєктах. Оновлення від npm додає перешкоду саме перед цими діями: після зміни email або використання recovery code для 2FA на чутливому акаунті вмикається автоматичний захисний стан на 72 години.

Це не каральний механізм і не про те, що npm «потрібен вам гіршою політикою». Це механічний стопор на тих точках, де компрометація дає найбільшу вигоду атакувальнику: керування акаунтом і публікацією.

Що реально змінюється в роботі команди

Ключове питання після спрацювання: “Що ще працює, а що точно не зможемо зробити?”

Що зазвичай триває:

  • Підготовка артефактів локально й у CI без фінальної публікації.
  • Тестування, оновлення changelog, перевірка залежностей.
  • Аналіз підозрілих змін у аудит-логах.
  • Підготовка комунікації для внутрішніх команд і споживачів.

Що зазвичай блокується:

  • Публікація нових версій npm-пакетів (publish), зміна критичних параметрів випуску.
  • Чутливі дії по акаунту, які могли б закрити шлях для атаки.
  • Швидке ручне “обійдемо зараз, розберемося потім”.

Навіть якщо конкретний перелік відрізняється залежно від типу акаунта, на практиці варто планувати так: публічний шлях релізу в цей момент закритий, а контрольний шлях має бути відкритим.

10-хвилинний план: не втратити темп під час read-only

  1. 0–2 хв: зафіксувати контур інциденту.
  • Хто ініціював зміну: email / recovery code / 2FA зміна.
  • Хто бачить статус акаунта та вікно 72h.
  • Запускаєте відлік часу в каналі інцидентів.
  1. 2–4 хв: оголошення інцидентного стану.
  • Публікуєте повідомлення: “публікацію заморожено, працюємо в режимі підготовки та перевірки”.
  • Визначаєте спільний канал для технічних оновлень.
  1. 4–6 хв: заморозити ризиковані кроки.
  • Зупиняєте автоматичні задачі публікації.
  • Блокуєте ручні publish-запити до з’ясування статусу.
  1. 6–8 хв: активувати резервний шлях.
  • Підтверджуєте, хто може взяти контроль через другого maintainer або альтернативний trusted publishing path.
  • Перевіряєте, що publish token не прив’язаний до однієї людини чи одного місця зберігання.
  1. 8–10 хв: план комунікацій і доказів.
  • Готуєте коротке повідомлення для споживачів пакетів: затримка релізу, причина, ETA перегляду.
  • Записуєте дії в лог події.

Після перших 10 хвилин команда переходить у тихий режим відновлення: перевіряє, чи була справжня атака, хто мав легітимний доступ, і де саме зламався ланцюжок постачання.

Як це пов’язати з 2FA та recovery code по-людськи

2FA без recovery code теж не дасть повної впевненості: recovery code важливий для аварійного доступу, але саме його використання є потенційно чутливою подією. Новий механізм змушує сприймати цю подію не як технічну дрібницю, а як тригер безпеки. Provenance у цій парі — третя ланка: якщо зловмисник усе ж публікує пакет, споживач і ваші платформи отримують доказову базу походження.

Найкраща практика:

  • 2FA вмикається на всіх maintainer-акаунтах.
  • Recovery code зберігається окремо за політикою секретності, доступ обмежено.
  • Provenance увімкнений для критичних пакетів, щоб у разі інциденту довести підписану історію.

Антипатерни, які варто прибрати сьогодні

  • Один-єдиний maintainer на всіх ролях публікації.
  • Невизначений шлях для аварійного релізу без альтернативи через політику організації.
  • Публічні секрети в CI та відсутність ротації publish token.
  • Реакція на алерт лише через “запросити всіх у Slack”, без заздалегідь затвердженого шаблону комунікацій.
  • Ігнорування першої хвилини після спрацювання lock як “тимчасова технічна помилка”.

Джерела

Короткий чеклист

  • Підтвердити, який саме акаунт у high-impact зоні та хто має право публікації.
  • Підготувати резервний шлях публікації через іншого maintainer або політику організації, а не через один акаунт.
  • Окремо зафіксувати процедуру сповіщення інженерів та споживачів про 72-годинний захист.
  • Періодично тренувати сценарій read-only, але без реальних змін публічних пакетів.

Склади 72-годинний план дій для npm-команди

Ти — техлід або DevOps-відповідальний команди, яка публікує npm-пакети. Завдання: зроби готовий план дій, щоб команда не розгубилась, якщо акаунт maintainer переходить у 72-годинний read-only. Вхідні дані: - Перелік пакетів і репозиторіїв, що залежать від автоматичної публікації. - Імена людей із правом публікації в npm і їхні резервні ролі. - Наявність 2FA на всіх критичних акаунтах. - Поточні CI/CD кроки для публікації: процеси, секрети, токени. - Контактна схема інцидентів: канал, канал для керівника зміни, ескалація. Виведи: 1) Перші 10 хвилин дій по хвилинно-маркерах із відповідальними. 2) Таблицю "що доступно / що заборонено" під час read-only. 3) План резервного шляху публікації на випадок, якщо основний акаунт під замком. 4) Шаблон комунікації в Slack/чат для внутрішніх команд та споживачів пакетів. 5) Перевірочний список на 24 години (ownership, 2FA, recovery code, provenance). Формат відповіді: 1) коротке резюме (до 80 слів), 2) Markdown-таблиці та чеклісти, 3) фінальний список відповідальних осіб і дедлайнів.