Почему npm 12 запрещает запускать скрипты без вашего разрешения?

GitHub готовит к выходу npm версии 12, и у многих разработчиков уже начались вопросы после первого знакомства с changelog. Самое заметное изменение касается жизненного цикла установки пакетов: скрипты preinstall, install и postinstall больше не будут запускаться автоматически для зависимостей. По умолчанию они заблокированы, и чтобы разрешить их выполнение, нужно явно это подтвердить.
Почему npm 12 запрещает запускать скрипты без вашего разрешения?
Изображение носит иллюстративный характер

Причина такого решения прямая. GitHub называет установочные скрипты «крупнейшей поверхностью для выполнения произвольного кода во всей экосистеме npm». Когда вы запускаете npm install, выполняются скрипты не только из ваших прямых зависимостей, но и из всех транзитивных: зависимостей зависимостей, которые могут уходить на несколько уровней вглубь. Один скомпрометированный пакет где-то в этом дереве способен запустить произвольный код прямо на машине разработчика или на CI-сервере. Именно это и называют атаками на цепочку поставок программного обеспечения, и npm 12 целенаправленно сужает эту точку уязвимости.
Модель безопасности меняется с «доверять по умолчанию» на «явное одобрение». Раньше пакет мог делать почти что угодно в момент установки, если только разработчик специально не передавал флаг --ignore-scripts. Теперь логика перевёрнута: ничего не выполняется без вашего ведома.
Помимо скриптов жизненного цикла, npm 12 вводит аналогичные ограничения для нескольких других категорий зависимостей. Git-зависимости теперь заблокированы по умолчанию, и флаг --allow-git по умолчанию выставлен в none. Зависимости, подключаемые через удалённые URL (например, HTTPS-архивы), тоже блокируются без явного --allow-remote. Нативные сборки через node-gyp для пакетов с файлом binding.gyp раньше запускались автоматически даже без явного скрипта установки; теперь это тоже требует разрешения. Скрипты prepare для Git-, файловых и символических зависимостей обрабатываются по той же логике.
Отдельного внимания заслуживает закрытая брешь с --ignore-scripts. До npm 12 этот флаг считался достаточной защитой: он запрещал выполнение скриптов из package.json. Но через Git-зависимость можно было подсунуть файл .npmrc, который переопределял сам исполняемый файл git. Код выполнялся, даже когда --ignore-scripts был активен. Перевод --allow-git в none по умолчанию именно это и закрывает.
Для тех, кто собирается мигрировать на npm 12, GitHub предлагает конкретную последовательность действий. Сначала нужно обновиться до npm 11.16.0 или выше: именно с этой версии появились предупреждения о скриптах, которые будут заблокированы в следующей мажорной версии. Запустите обычный npm install и посмотрите на предупреждения в выводе: они покажут, какие пакеты используют скрипты. Затем запустите:
npm approve-scripts --allow-scripts-pending
Эта команда выведет список пакетов со скриптами, ожидающими одобрения. Вы проверяете каждый, разрешаете те, которым доверяете, и коммитите обновлённый package.json. После перехода на npm 12 одобренные скрипты продолжат работать, а всё, что не получило явного разрешения, запускаться перестанет.
Раньше в этом году GitHub уже добавил в npm похожую по духу функцию min-release-age: настройку, позволяющую отклонять любые версии пакетов, опубликованные менее чем за указанное количество дней до установки. Смысл тот же: дать разработчику время на обнаружение вредоносного пакета до того, как он попадёт в продакшн. npm 12 строится на той же логике временного карантина и явного контроля.
Практически это означает, что проекты с нативными зависимостями (типичный случай: пакеты вроде bcrypt или canvas, использующие node-gyp и binding.gyp) потребуют ручной проверки перед миграцией. CI-пайплайны, где npm install запускается автоматически, тоже нужно будет привести в порядок заранее. Если этого не сделать, сборки просто сломаются после обновления. Выход npm 12 запланирован на следующий месяц, так что время на подготовку ещё есть, но его уже немного.


Новое на сайте

20965Что делать с уязвимым SonicWall GMS без будущих обновлений? 20964Как ошибка APT позволяет подменить пакет и получить root-доступ? 20963Могут ли две уязвимости Xen открыть одной виртуальной машине память всего хоста? 20962Как рекламный промпт проник в настройки OpenAI Codex? 20960Apple начнёт проверять публичные ссылки на файлы в iCloud 20959Что известно о предупреждении mSecure и какие меры принять? 20958Как LLMjacking превращает корпоративные ИИ-ресурсы в чужой бизнес? 20957Что делать администраторам cPGuard после взлома канала обновлений? 20956Бэкдор в телевизоре: как Google остановила сеть из 1,3 млн Android-устройств 20955Кто может получить доступ к кошелькам через плагин CryptoPayment Gateway? 20954Критическая уязвимость Siemens IoT2050 открыла путь к удалённым командам 20953Взлом Chainstack: под угрозой оказались данные клиентов и хеши паролей 20952Четыре проверки, которые помогают найти уязвимости с реальным риском 20951Две уязвимости Barracuda открывают путь к root-доступу
Ссылка