Инцидент (https://www.opennet.me/opennews/art.shtml?num=44104) с нарушением работы многих известных проектов после удаления модуля из NPM-репозитория, привёл к обсуждению незащищённости NPM от атак, инициированных со стороны разработчиков модулей. В том числе раскрыты (http://blog.npmjs.org/post/141702881055/package-install-scri...) данные об незащищённости (https://www.kb.cert.org/vuls/id/319816) инфраструктуры NPM к атаке по
внедрению (https://medium.com/@nm_johnson/npm-package-hijacking-fr...) в репозиторий самораспространяющихся вредоносных модулей.Совершению атаки способствуют несколько факторов:
- Использование семантического версионирования (https://docs.npmjs.com/getting-started/semantic-versioning) (SemVer), по умолчанию не привязывающего приложение к конкретным версиям модулей, что позволяет инициировать установку обновления модуля через выпуск его новой версии;
- Применение постоянного кэширования параметров аутентификации в NPM - после совершения входа с машины разработчика можно выполнять любые действия от его имени, пока разработчик вручную не отсоединиться от репозитория. Подобный подход мешает разработчику контролировать свою активность в репозитории, что может быть использовано для скрытой публикации обновлений с его компьютера.
- Использование централизованного реестра, который используется большинством систем на базе платформы Node.js. Любой опубликованный модуль сразу становится доступен для всех, без прохождения какой-либо проверки;- Возможность определения shell-скриптов (https://docs.npmjs.com/misc/scripts), запускаемых на различных этапах установки модуля и позволяющих выполнить любые действия на системе пользователя.
Сценарий атаки сводится к подготовке модуля, который через автоматически запускаемый установочный скрипт создаёт и публикует новый вредоносный модуль, а также добавляет этот вредоносный модуль в список зависимостей к модулям, которые разрабатываются на текущем компьютере. Внедрение подобного модуля на незащищённую систему разработчика одного из популярных модулей NPM приведёт к цепной реакции - в репозиторий будет отправлена новая версия популярного модуля, привязанная через зависимости к вредоносному модулю.
Публикация с уровнем "bugfix" приведёт к установке обновления большинством пользователей. Далее, цепочка повторяется, при установке модуля будет запущен вредоносный скрипт, который изменит модули, разрабатываемые текущим пользователем и опубликует их. Все операции по побликации будут выполнены без участия разработчика, так как сеанс подключения к репозиторию NPM прокэширован.Отличная возможность для внедрения вредоносных модулей появилась после инцидента с модулем kik, автор которого удалил из репозитория свои 273 модуля, связанные зависимостями со многими проектами. Злоумышленник мог разместить в репозитории новые модули с теми же именами и они были бы установлены на системах, в которых удалённые модули были упомянуты в зависимостях.
В результате эксперимента исследователю безопасности удалось (https://medium.com/@nm_johnson/npm-package-hijacking-fr...) перехватить контроль над 238 из 273 удалённых модулей.
Для первичного внедрения вредоносного кода также могут быть использованы методы социальной инженерии, например, атакующий может отправить разработчику сообщение о конфликте или проблемах с определённым модулем, для проверки проблемы разработчик установит данный модуль и тем самым запустит цепочку распространения червя.Для блокирования подобных атак разработчикам модулей рекомендуется не использовать постоянное подключение к NPM, установить "npm shrinkwrap" для привязки зависимостей и использовать при установке опцию "npminstall ... --ignore-scripts" для игнорирования установочных скриптов.
В качестве рекомендуемых мер усиления безопасности инфраструктуры NPM, которые помогут избежать проведения подобных атак, предлагается:
- Ввести ограниченное время жизни параметров входа;
- Применять двухфакторную аутентификацию при публикации модулей (например, ввести обязательное подтверждение операции по SMS);
- Производить отключение от репозитория перед выполнением операции установки модулей;
- Ввести обязательное ручное подтверждение выполнения скриптов, вызываемых перед установкой или удалением модуля;
- Включить по умолчанию shrinkwrap (https://docs.npmjs.com/cli/shrinkwrap) для организации привязки проекта к конкретной версии модуля;
- Вынести процесс обновления версий в отдельно подтверждаемую операцию "npm upgrade";
- Внедрить систему проверки и рецензирования публикуемых модулей.
URL: https://medium.com/@nm_johnson/npm-package-hijacking-fr...
Новость: http://www.opennet.me/opennews/art.shtml?num=44111
коммитим репо -> обновляемся -> проверяем что пришло
Тут все проще. "Дистрибутив" жидко обкакался. И пытается все свалить на разработчиков.По факту же, в любом дистрибутиве все зависит от разработчиков. Просто есть свободные дистры, в которых все правильно сделано умными людьми. А есть коммерческие дистры, где правильно стараются делать из за клиентов и денег. А это ни то ни се.
Какой дистрибутив? Вернее дистрибутив чего?
Все правильно, проекту пора "взрослеть".
Что уж там..., проекту пора "умирать".
нпму в текущем виде действительно надо умереть как можно скорее, иначе ничего нового не родится
На яваскрипте сложно писать большие проекты, поэтому вместо взрослоты - хипстота. И даже пример десятилетий успешной работы других пакетных манеджеров не помог.
>Использование семантического версионирования по умолчанию не привязывающего приложение к конкретным версиям модулейТолько JS макаки могли додуматься до такого.
У них там CouchDB без привилегий, можно заливать все что угодно и любых размеров.
если бы не жил в пещере, знал бы что это, на данный момент, распространенная практика не только в js сообществе.
Ну не знаю, у нас в Java мире везде надо версии указывать. Без них не работает.
мда.. в Java где всё идет через коммерческий mavencentral и где тебе с "непонятного" источника прилетают скомпилированные классы, - это не лучший пример для подражания в подобных ситуациях.cargo в Rust, более совершенен, да там semver, на все пакеты приходят в исходниках на машину, все пакеты хостятся на гитхабе(публичный ревью).
> cargo в Rust, более совершенен, да там semver, на все пакеты приходят в исходниках на машину, все пакеты хостятся на гитхабе(публичный ревью).Чем это отличается от сабжа?
Я сильно не знаком с NPM, хоть и пользовался им, но непонятна ситуация с владельцами NPM, которые могут на свое усмотрение, где-то у себя поменять привязку пакета "foo" с оригинального на платный(с трояном, от сп.служб и т.д) и это до загрузки не проверить.cargo индекс, виден всем (на гитхабе) и человек может понять перед загрузкой, кто, когда и где стоит за таким-то пакетом перед загрузкой его через cargo!
Кроме-то в Rust(cargo) сейчас запрещены вайлдкарды версий(*) в зависимостях, т.е изначально версии перед публикацией фиксируется. Их можно изменить на определенный диапазон (e.g: "1.1.1=<1.1.4"), но так делают только авторы которые и писали сам пакет и его пакет-зависимость.
> cargo индекс, виден всем (на гитхабе) и человек может понять перед загрузкой, кто, когда и где стоит за таким-то пакетом перед загрузкой его через cargo!Чем это отличается от сабжа? (2)
> в Rust(cargo) сейчас запрещены вайлдкарды версий(*) в зависимостях, т.е изначально версии перед публикацией фиксируется
Запрещены - и ладно, в NPM подобных запретов нет, NPM лишь предоставляет инструмент/возможность, а то, как им пользоваться - на усмотрение конечного разработчика.
> Я сильно не знаком с NPM, хоть и пользовался им,...но мнение имею. Молодец, настоящий адепт cargo-культа. Садись, пять.
Т.е. владельцам NPM ты не доверяешь, а владельцам Гитхаба -- всем сердцем и душой?
> но непонятна ситуация с владельцами NPMКак и с любым другим онлайн-сервисом. Хочешь надежности -- проверяй и держи на своих машинах.
> cargo индекс, виден всем (на гитхабе) и человек может понять перед загрузкой, кто, когда и где стоит за таким-то пакетом перед загрузкой его через cargo!
Как и в любом другом хранилище пакетов. Но см пункт 1 -- ты никогда не сможешь гарантировать, что чужой сервис вернет тебе правильную информацию.
> Кроме-то в Rust(cargo) сейчас запрещены вайлдкарды версий(*) в зависимостях
В любой системе зависимостей можно выбрать -- привязаться к последней версии или по * -- это исключительно выбор разработчика. Наркоманское ограничение в cargo, кстати, только говорит о его убогости -- да, да когда-нибудь кому-нибудь может понадобиться эта фича и придётся городить костыли с авто-генератором зависимостей для билд-скрипта.
Любопытно, как при таком подходе решается ситуация конфликта версий. Вот некая программа требует десяток модулей конкретной версии, каждый из этих модулей тоже требует конкретных версий других модулей. И есть какой-нибудь очень часто используемый модуль, ну типа isarray или leftpad из предыдущей новости. И вот у тебя в программе есть пятьдесят модулей, каждый из которых привязан к разной версии некого isarray. Что происходит в таком случае? Вопрос хранения и загрузки с сервера решит какой-нибудь vcs, но что происходит в момент исполнения программы? В память загружается пятьдесят разных версий модуля?
Не знаю как в "голой" яве (раньше часто в саму jar-ку приложения сразу библиотеки нужных версий всовывали), а вот в Weblogic'е (наверное и в других серверах приложений тоже) есть старое банальное понятие "разделяемой библиотеки" (shared library). Такая библиотека имеет номер версии. А в приложениях (в дескрипторе развертывания), которые потом деплоятся на сервер приложений и используют эту библиотеку, ты указываешь номер требуемой версии, причем можешь указать "строго этот номер версии" или "начиная с этого номера и выше". На сервере приложений крутится несколько нужных версий одной и той же shared library. При деплое приложения сервер подсовывает нужную версию в зависимости от того что указано в дескрипторе развертывания этого приложения (ну или ошибку, если нет нужной версии)
это одна из причин по которой жабасофт считается (и является) убогим говном.
Развитие QA, DevOps, и т.д. и переход из в JS-разработчики делают своё дело
О да, прибивать гвоздями к минорной версии - лучше, конечно.
> О да, прибивать гвоздями к минорной версии - лучше, конечно.Зачем же бросаться в крайности? О ранжировании не слышали?
Я просто этот Java мир видел вблизи - там обычно именно миноры гвоздями и прибивают, хотя Maven очень гибок в это плане.
О, ну неужели они всё-таки это заметили?
Ну вот обязательно надо было собрать все мыслимые грабли? На чужом примере учиться - никак?
> Ну вот обязательно надо было собрать все мыслимые грабли?И ряд немыслимых типа https://www.youtube.com/watch?v=1TioQx2jVN0 ...
> На чужом примере учиться - никак?
Это удел мудрых.
Кто то говорил, что на js меньше ошибок на кол-во кода.
Как может быть меньше того, чего нету совсем?
> Кто то говорил, что на js меньше ошибок на кол-во кода.
> Как может быть меньше того, чего нету совсем?Выгнали с работы в кризис и отдали набивание иксымелей для жабы индусу-аутсорсеру? Ничо страшного! Ты всегда можешь стать дворником и зарабатывать примерно столько же, сколько тот индус, а валютную ипотеку вернёшь почкой.
народ, хорош шлак изливать. все такие маркетологи, а кто код писать будет? ну хоть кто-то может вектор для исправления ситуации дать? а то пока все работали вопросов как-то ни кто не задавал, зато теперь реквиумы и оды у всех прут. противно. блин.
проще некуда: запилить новый нпм с ссл, гитом, подписями и без шавок у руля.
> сслПри чем тут SSL?
Кто будет проверять соответсвие подписи и личности автора?
Храните свои подписи в блокчейне и будет вам счастье.
Счастья будет много. В биткоине более 30Гб уже.
> Кто будет проверять соответсвие подписи и личности автора?Поинтересуйтесь, как этот вопрос решается в различных дистрибутивах Linux. Например, в Debian.
> проще некуда: запилить новый нпм с ссл, гитом, подписями и без шавок у руля.... на питоне...
> ... на питоне...Который не тормозит еще больше чем js.
пора на http://jspm.io/ сваливать
> npm install systemjsа там копирастический червь скачается?
> Включить по умолчанию shrinkwrap для организации привязки проекта к конкретной версии модуляКак они умудрились до сих пор это не включить? Я не представляю, как можно вообще без shrinkwrap можно чего-то разрабатывать.
Легко и просто: захерачиваешь node_modules в свн/гит и никаких тебе ужасов с npm install. Раз в несколько месяцев обновляешься, ну или когда нужно добавить новый модуль. И волосы твои мягкие и шелковистые.
+ независишь от интернета/авторов, выпиливающих свои модули/политиков, блокирующих гитхаб
+ нормальные, повторяемые сборки