В этой статье объясняется важность понимания того, как работают сценарии жизненного цикла npm, такие как preinstall и postinstall, как они могли (и использовались) злонамеренно использоваться, и предлагает несколько советов о том, что вы можете с этим сделать в рамках здоровья вашего проекта npm.

Проблема

Если вы используете npm, популярный менеджер пакетов JavaScript, вы, вероятно, слышали об атаке на пакеты eslint-scope, когда контроль над сильно зависящим от него пакетом был получен злоумышленником, который опубликовал новую версию, содержащую вредоносные программы. код. Этот вредоносный код был выполнен с использованием postinstall сценария жизненного цикла, то есть каждый пользователь, установивший пакет, потенциально мог получить данные для входа в реестр npm, отправленные на удаленный адрес вредоносным сценарием. Официальный отчет об инциденте npm можно найти здесь, но важная деталь заключается в том, что по незнанию пользователи, выполняющие знакомую команду npm install, не подозревали, что этот вредоносный код выполнялся на этапе postinstall. Поскольку эти сценарии выполняются по умолчанию, любые выполняемые ими фоновые задачи часто скрыты от пользователя, который только ищет отзывы о том, готово ли новое, которое они установили, или нет.

Пример:

// package.json file
"name: "express-example-package",
"scripts": {
  "postinstall": "node malicious.js"
}

Если вышеупомянутый файл package.json был примером пакета в реестре npm, любой пользователь, решивший npm install express-example-package выполнить указанный выше postinstall сценарий - содержимое этого файла сценария может быть любым! Такое же поведение справедливо для скриптов preinstall, postinstall, preuninstall и postuninstall. Ссылка npm на эти скрипты доступна здесь.

Профилактика

На самом деле предотвратить эту проблему намного сложнее, чем одно простое решение. Эти хуки жизненного цикла являются важной функцией - они могут помочь настроить пакеты сложными способами и выполнить важные задачи очистки или подготовки, поэтому простое отключение этих хуков может быть ограничивающим. Поэтому для предотвращения этой проблемы рекомендуется всегда 1) внимательно проверять зависимости и использовать файл блокировки для предотвращения автоматической установки новых пакетов.

2) Отказаться от запуска скриптов при установке

При установке пакета вы можете отказаться от запуска скриптов, используя параметр ignore-scripts в npm или Yarn:

npm install --ignore-scripts

yarn add --ignore-scripts

Или, если вы никогда не хотите запускать эти сценарии при установке пакетов, вы можете изменить свою глобальную конфигурацию npm:

npm config set ignore-scripts true

yarn config set ignore-scripts true

Примечание: этот параметр также можно добавить в файл проекта .npmrc или .yarnrc.

3) Проверить использование скрипта текущих модулей

Я обнаружил, что не хватает инструментов, чтобы увидеть, какие зависимости в текущем дереве зависимостей в настоящее время выполняют сценарии жизненного цикла, поэтому опубликовал инструмент cli для просмотра этой информации. Это доступно на npm.

Чтобы использовать этот инструмент, вы можете установить его глобально npm install npm-viewscripts -g.

Внутри каталога проекта запуск npm-viewscripts предоставит список всех установленных в настоящее время зависимостей, которые имеют, и продолжит запускать сценарий при установке или удалении.

Мои мысли

Этот тип уязвимости не является ошибкой npm, поскольку эти сценарии жизненного цикла являются очень полезной функцией для управления пакетами, однако пользователи должны понимать риски. Можно утверждать, что проблема имеет более широкий масштаб с npm из-за большого размера дерева зависимостей типичного приложения Node.js, а также философии создания, совместного использования и использования множества небольших и дискретных модулей.

Я думаю, что важно, чтобы сообщество и, в частности, сопровождающие популярных пакетов приняли меры предосторожности для предотвращения продолжения этих атак - лучшая профилактика - включить 2FA для всех учетных записей npm с доступом на запись в пакеты. Если этот параметр включен, любые учетные данные npm, которые были украдены тем или иным способом, наносят меньше вреда потребителям пакета, но это, конечно, ничего не делает, чтобы предотвратить внезапное мошенничество доверенного сопровождающего.

npm проделывают огромную работу по снижению риска подобных атак, сокращая количество случаев типосквоттинга и предлагая бесплатные инструменты безопасности, такие как npm audit.