Примечание редактора: это гостевой пост от Адама Болдуина из ^ Lift Security и Node Security Platform. Как мы обсуждали в предыдущих сообщениях, Адам проводит постоянные проверки безопасности реестра и его содержимого и держит нас в курсе всего, что может поставить под угрозу нашу безопасность.

За эти годы я потратил много времени на изучение полумиллиона общедоступных пакетов на npm. С этими общедоступными пакетами идут миллионы общедоступных tar-архивов, а это значит, что нужно просматривать и экспериментировать с большим количеством кода. В этом коде скрыто удивительное количество конфиденциальной информации: токены аутентификации, пароли и данные производственных испытаний, включая номера кредитных карт.

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

npm опубликовать

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

Когда вы запускаете npm publish, npm объединяет все файлы в текущем каталоге. Он принимает за вас несколько решений о том, что включать, а что игнорировать. Для принятия этих решений он использует содержимое нескольких файлов в каталоге вашего проекта. Эти файлы включают .gitignore, .npmignore и массив файлов в package.json. Он также всегда включает одни файлы и игнорирует другие.

npm всегда будет включать эти файлы в пакет:

  • package.json
  • README и его варианты, например README.md
  • CHANGELOG и его варианты
  • LICENSE и альтернативное написание LICENCE

npm всегда будет игнорировать эти шаблоны имен файлов:

  • .*.swp
  • ._*
  • .DS_Store
  • .git, hg, .svn, CVS каталоги управления версиями
  • .npmrc
  • .lock-wscript
  • .wafpickle-*
  • config.gypi
  • npm-debug.log

.gitignore против .npmignore

Один из наиболее распространенных способов исключения файлов и папок - указать их в .gitignore файле. Это связано с тем, что файлы, которые вы не хотите фиксировать в своем репозитории, также обычно являются файлами, которые вы не хотите публиковать.

npm также поддерживает файл с именем .npmignore, который ведет себя точно так же, как .gitignore. Эти файлы не являются накопительными. Добавление .npmignore файла в ваш проект полностью заменяет .gitignore. Если вы попытаетесь использовать оба, вы случайно опубликуете файл, который, как вы думали, исключили.

Вот как это могло произойти:

  • Вы добавляете свой production.json файл конфигурации в свой .gitignore файл, потому что он содержит конфиденциальную информацию.
  • Затем вы добавляете .npmignore, но забываете добавлять к нему какие-либо файлы.
  • Вы запускаете npm publish.
  • Поскольку .npmignore существует, к нему обращаются вместо .gitignore, но в нем нет файлов, которые следует игнорировать!
  • Таким образом, ваш production.json файл публикуется, и утечка вашей конфиденциальной информации.

По возможности придерживайтесь .gitignore! Если вы используете другую систему контроля версий, используйте .npmignore. Если вы используете git и имеете файл игнорирования, но хотите опубликовать некоторые файлы, которые вы не фиксируете - возможно, результат шагов сборки - начните с копирования вашего .gitignore файла в .npmignore. Затем отредактируйте, чтобы удалить файлы, которые вы не хотите в git, но хотите в своем пакете.

Добавление файлов в белый список с помощью массива files

Есть еще лучший способ контролировать, какие именно файлы публикуются вместе с вашим пакетом: занесение в белый список с массивом файлов. Только 57 000 пакетов используют этот метод контроля того, что в них входит, вероятно, потому, что он требует от вас инвентаризации вашего пакета. Однако это, безусловно, самый безопасный способ сделать это.

Массив files определяет каждый файл или каталог для включения в вашу публикацию. Включены только эти файлы, плюс те, которые всегда включены в npm (например, package.json), за вычетом тех, которые запрещены другим правилом.

Вот package.json файл с массивом файлов:

{
  "name": "@adam_baldwin/wombats",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "files": [
   "index.js"
  ],
  "keywords": [],
  "author": "Adam Baldwin <[email protected]> (https://liftsecurity.io)",
  "license": "ISC"
}

Независимо от того, какие еще файлы существуют в этом каталоге проекта в течение npm publish, в архив будет упакован только файл index.js (плюс, конечно же, файл readme и package.json!)

Перепроверьте свою работу

Вы можете использовать модуль npm-packlist для программного получения списка файлов, которые npm будет включать в определенный каталог. Вы также можете запустить сам npm, чтобы узнать, что он будет включать. Эта команда перечисляет файлы, которые будут упакованы:

tar tvf $(npm pack)

Использование токенов только для чтения

Если вы используете частные модули в системе непрерывной интеграции (CI), вам необходимо предоставить этой службе токен аутентификации. Раньше вам приходилось предоставлять обычный токен аутентификации из вашего .npmrc, что дает вашей системе CI возможность делать все, что вы можете делать с вашей учетной записью npm. Теперь можно сгенерировать токен только для чтения, который может ограничить ущерб в случае утечки токена через CI.

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

curl -u [USERNAME]:[PASSWORD] https://registry.npmjs.org/-/npm/v1/tokens \
-X POST -H 'content-type: application/json' \
-d '{"password":"[USERNAME]", "readonly": "true"}'

Вы можете просмотреть и удалить созданные вами токены через веб-сайт npm. под Вашим профилем ›Токены.

Что делать, если вы опубликовали конфиденциальные данные

Если вы случайно опубликовали модуль, содержащий конфиденциальную информацию, вы должны считать эти данные скомпрометированными. Было бы неплохо, если бы вы могли просто отменить публикацию модуля и надеяться, что никто не заметил ошибку, но на самом деле, как только вы публикуете модуль, он реплицируется на все зеркала реестра и другие третьи стороны, например ^ Lift. Единственный способ гарантировать, что ваши услуги и данные не будут скомпрометированы, - это сделать недействительными и изменить любые опубликованные ключи API или пароли.

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

Попробуйте добавить в белый список!

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

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