Не ходите в npmjs.com напрямую
Чтобы избежать уязвимостей нулевого дня, MITM, и всевозможных «подарочков» от активистов и хакеров, можно проксировать и кэшировать реестр npm на уровне собственной инфраструктуры.
Готовые решения вроде Verdaccio и Nexus добавят слой безопасности, ускорят установку пакетов и позволят хостить свои приватные пакеты бесплатно в неограниченном количестве. При желании, можно реализовать свой npm‑прокси так, чтобы в него попадали только версии пакетов старше, скажем, двух недель — за это время у коммьюнити будет время обнаружить и устранить проблему.
Скрипты жизненного цикла npm‑пакетов
В ходе разработки, многие находят скрипты жизненного цикла npm весьма полезными, например, в «prepare» можно настроить установку git‑хуков, а в «preinstall» можно проверить наличие необходимых внешних зависимостей и их версий.
А вы задумывались над тем, что любой установленный вами npm‑пакет тоже может иметь такие скрипты? И они так же могут читать переменные окружения, бродить по файловой системе, запускать произвольные команды, отправлять что‑либо по сети и т. д.
Изучите, какие скрипты жизненного цикла используются в ваших зависимостях, и если там нет ничего критичного (например, бутстраппинга нативных node‑модулей), устанавливайте их с флагом --ignore-scripts
. Если же запускать какие‑то скрипты необходимо, запускайте их выборочно, вручную. При этом, когда установка происходит в автоматизированном окружении, убедитесь, что этот шаг максимально изолирован и имеет минимальное количество привилегий, достаточное для его работы.
Кстати, файл
.npmrc
из ненадежного источника так же может представлять существенную опасность, потому что с его помощью можно заставить npm выполнять произвольный код.
«Крышечки»
Не оставляйте в package.json плавающие версии зависимостей, как минимум, по четырем причинам:
Массово апгрейдить зависимости вслепую — отличный способ притащить в проект малварь;
Не все пакеты используют semver, и если вы будете оставлять «крышечку» где попало, то рискуете апгрейднуться до несовместимых изменений тогда, когда вы этого не планировали;
Баги в принципе не следуют semver‑у, поэтому делать плавающим «патч» — иллюзия безопасности;
Если два разработчика захотят поставить один и тот же пакет в плавающией версии, его итоговую версию будет определять не package.json, а package-lock.json — сложнее мержить.