В начале августа в нескольких десятках npm-пакетов был обнаружен вредоносный код. Администрация npmjs.com оперативно на это отреагировала и тут же подготовила отчёт о предпринятых мерах. Позже Доминик Кундел из twilio.com поделился советами о том, как найти проекты, «заражённые» подобными пакетами. Представляем вашему вниманию рассказ об этих событиях.


Вредоносный пакет crossenv в npm-реестре


1-го августа сего года нам, администрации npmjs.com, сообщили в Twitter о том, что пакет, имя которого очень напоминало популярный cross-env, отправляет на npm.hacktask.net переменные окружения из контекста его установки. Мы немедленно провели расследование и удалили из реестра этот пакет. Дальнейшее изучение ситуации привело к обнаружению в реестре ещё около 40 вредоносных пакетов.

19 июля пользователь hacktask опубликовал некоторое количество пакетов, имена которых были очень похожи на имена популярных npm-пакетов. Мы называем данное явление «typo-squatting», это — захват некоего ресурса из-за опечатки. Ранее подобное происходило, в основном, случайно. Несколько раз мы видели умышленное использование такого способа именования пакетов, к которому прибегали авторы библиотек, конкурирующих с уже существующими пакетами. Сейчас же имена пакетов были подобраны специально, и сделано это было явно со злым умыслом. А именно, автор пакетов намеревался красть данные у введённых в заблуждение пользователей. В результате все пакеты пользователя hacktask были удалены из реестра.

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

?Список вредоносных пакетов


Вот список пакетов пользователя hacktask с общим количеством их загрузок за период с 19 по 31 июля. Число загрузок этих пакетов возросло сразу после обнаружения вредоносного кода, что вызвано всеобщим интересом к проблеме. Данные по загрузкам до нахождения проблемы более точно отражают масштаб происшествия. Обратите внимание на то, что около сорока загрузок — это типичное число для любого общедоступного пакета, опубликованного в реестре, так как это соответствует числу автоматических загрузок на зеркала реестра. Учитывая это, вы можете видеть, что реальная угроза исходит от пакета crossenv, который набрал почти 700 загрузок, на втором месте — пакет jquery.js. Однако, тут также нужно учитывать то, что большинство загрузок выполнено зеркалами, которые запрашивали копии 16-ти опубликованных версий пакета crossenv. Мы оцениваем число реальных установок crossenv примерно в 50, возможно, их ещё меньше.

  • babelcli: 42
  • cross-env.js: 43
  • crossenv: 679
  • d3.js: 72
  • fabric-js: 46
  • ffmepg: 44
  • gruntcli: 67
  • http-proxy.js: 41
  • jquery.js: 136
  • mariadb: 92
  • mongose: 196
  • mssql-node: 46
  • mssql.js: 48
  • mysqljs: 77
  • node-fabric: 87
  • node-opencv: 94
  • node-opensl: 40
  • node-openssl: 29
  • node-sqlite: 61
  • node-tkinter: 39
  • nodecaffe: 40
  • nodefabric: 44
  • nodeffmpeg: 39
  • nodemailer-js: 40
  • nodemailer.js: 39
  • nodemssql: 44
  • noderequest: 40
  • nodesass: 66
  • nodesqlite: 45
  • opencv.js: 40
  • openssl.js: 43
  • proxy.js: 43
  • shadowsock: 40
  • smb: 40
  • sqlite.js: 48
  • sqliter: 45
  • sqlserver: 50
  • tkinter: 45

Если вы загрузили и установили что-то из этого списка, вам следует немедленно деактивировать или поменять любые учётные данные, которые могли находиться в shell-окружении.

?О дальнейших действиях по защите реестра


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

Мы поддерживаем Lift Security и Node Security Project в их текущей работе по выполнению статического анализа общедоступных пакетов, но эти усилия не позволят найти абсолютно все проблемные пакеты. Определение того, содержит ли пакет нечто вредоносное при публикации, конечно, эквивалентно проблеме останова, сделать мы этого не можем.

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

Как найти проекты, «заражённые» вредоносными npm-пакетами


Вот скриншот из твита Оскара Болмстена, благодаря котоому в npmjs.com узнали о том, что пакет crossenv, вероятно, ворует переменные окружения.


Анализ пакета crossenv

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

?Проверка проектов на наличие в них вредоносных пакетов


Пакеты, о которых идёт речь, были удалены из реестра, однако, так как кража данных осуществляется в ходе установки пакета, вам следует проверить, не установили ли вы один из них. Иван Акулов собрал список этих пакетов и опубликовал его в своём блоге. Кроме того, он написал небольшую программу, которую вы можете использовать для проверки того, не используются ли эти пакеты в вашем текущем проекте:

npm ls | grep -E "babelcli|crossenv|cross-env.js|d3.js|fabric-js|ffmepg|gruntcli|http-proxy.js|jquery.js|mariadb|mongose|mssql.js|mssql-node|mysqljs|nodecaffe|nodefabric|node-fabric|nodeffmpeg|nodemailer-js|nodemailer.js|nodemssql|node-opencv|node-opensl|node-openssl|noderequest|nodesass|nodesqlite|node-sqlite|node-tkinter|opencv.js|openssl.js|proxy.js|shadowsock|smb|sqlite.js|sqliter|sqlserver|tkinter"

?Поиск «заражённых» проектов в Mac и Linux


Если вы, как и я, регулярно разрабатываете под Node.js, у вас может быть целый набор проектов, которые хорошо было бы проверить. Я расширил код Ивана именно по этой причине. В частности, я воспользовался командами find и xargs для сканирования всех поддиректорий папки, содержащей мои проекты. Каждый проект затем проверяется с помощью вышеприведённого кода. Запустить скрипт можно, просто скопировав его в командную строку:

find . -type d -maxdepth 4 -name node_modules -print0 | xargs -0 -L1 sh -c 'cd "$0/.." && pwd && npm ls 2>/dev/null | grep -E "babelcli|crossenv|cross-env.js|d3.js|fabric-js|ffmepg|gruntcli|http-proxy.js|jquery.js|mariadb|mongose|mssql.js|mssql-node|mysqljs|nodecaffe|nodefabric|node-fabric|nodeffmpeg|nodemailer-js|nodemailer.js|nodemssql|node-opencv|node-opensl|node-openssl|noderequest|nodesass|nodesqlite|node-sqlite|node-tkinter|opencv.js|openssl.js|proxy.js|shadowsock|smb|sqlite.js|sqliter|sqlserver|tkinter"'

Знаю, код получился немаленьким, поэтому объясню что тут к чему.

  • Скрипт, начиная с текущей директории, выполняет рекурсивный поиск папок с именем node_modules, используя команду find. Глубина поиска в настоящий момент ограничена 4-мя уровнями вложенности, но вы можете это изменить сообразно структуре ваших проектов.

  • Затем здесь применяется команда xargs, которая занимается исполнением кода для каждой строки (то есть — директории), возвращённой find.

  • Код, который будет исполнен, создаёт новый экземпляр оболочки, в котором будут выполнены следующие действия:

    1. Для начала оболочка переходит в родительскую директорию папки node_modules.

    2. Далее, выводится имя текущей сканируемой директории с использованием команды pwd. Обратите внимание, то, что будет выведено имя директории, не означает, что она «заражена».

    3. После этого запускается npm ls, что приводит к выводу всех установленных в проекте модулей.

    4. Так как команда npm ls может вывести сообщения о несуществующих зависимостях или о других ошибках, мы перенаправляем все сообщения, предназначенные для stderr, в /dev/null (то есть, просто отбрасываем их).

    5. Всё остальное передаётся grep для проверки на то, содержится ли там упоминание вредоносных пакетов. Если такой пакет будет найден, программа сообщит об этом с указанием пути к нему.

?Поиск «заражённых» проектов в Windows


Если вы работаете в Windows, вот PowerShell-скрипт, который написал Кори Уэзерс. Делает он то же самое, что и только что рассмотренная программа для Mac и Linux.

Get-ChildItem $directory -Directory -Recurse -Include "node_modules" | foreach { cd $_.FullName; cd ..; npm ls | Select-String -Pattern "babelcli|crossenv|cross-env\.js|d3\.js|fabric-js|ffmepg|gruntcli|http-proxy\.js|jquery\.js|mariadb|mongose|mssql\.js|mssql-node|mysqljs|nodecaffe|nodefabric|node-fabric|nodeffmpeg|nodemailer-js|nodemailer\.js|nodemssql|node-opencv|node-opensl|node-openssl|noderequest|nodesass|nodesqlite|node-sqlite|node-tkinter|opencv\.js|openssl\.js|proxy\.js|shadowsock|smb|sqlite\.js|sqliter|sqlserver|tkinter"} -ErrorAction Ignore

?Как понять, что был найден вредоносный пакет?


Вот как выглядит экран при обнаружении вредоносного пакета. Мы, в данном случае, в демонстрационных целях, искали пакет express.


Красным отмечено сообщение о найденном вредоносном пакете

?Что, если вредоносный пакет найден?


В подобной ситуации следует немедленно поменять все секретные данные, которые были сохранены в переменных окружения. Речь идёт, например, о паролях доступа к учётным записям, об API-ключах, и так далее. Если уязвимость найдена в проекте, над которым ведётся совместная работа, не забудьте оповестить об опасности всех разработчиков. Помните о том, что системы непрерывной интеграции и облачные хостинги так же используют переменные окружения. Поэтому, если один из подобных проектов попал в продакшн, или использует систему, в которой имеются переменные окружения, примите меры к тому, чтобы данные, которые могли попасть к злоумышленнику, оказались бесполезными.

?Если ничего не найдено — значит всё хорошо?


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

Кроме того, следует внимательно относиться, например, к тому, как используются сервисы, учётные данные которых хранятся в переменных окружения. Скажем, если речь идёт об аккаунте на Twilio, подозрение должен вызвать неожиданный скачок числа телефонных звонков или сообщений.

Итоги


Если окажется так, что вы обнаружите подозрительный npm-пакет, обязательно сообщите об этом в службу безопасности npmjs.com, написав им по адресу security@npmjs.com. Они исследуют ситуацию и, если опасения подтвердятся, удалят из реестра опасный пакет, а, возможно, и несколько пакетов.
Вредоносные npm-пакеты — явление сравнительно новое. Надеемся, все вместе мы сможем справиться с этой угрозой.

Уважаемые читатели! Доводилось ли вам сталкиваться с подозрительным поведением npm-пакетов?

Комментарии (46)


  1. Ivan_83
    08.08.2017 13:06
    +19

    Не пуганные идиоты.

    Осталось дождаться когда у какого нибудь лопуха-разработчика популярного пакета уведут учётку и зальют туда обновление с rm -rf / или ещё какими лулзами.

    Хуже всего что умные люди наверняка давно залили туда код который шпионит по тихому и не палится, в отличии hacktask которому оно было просто ради интереса. Обзовись он какимнить Ralf Murrey и пр рандомными именами по одному на каждый пакет и чуть позаботься о скрытности его бы никогда не нашли.


    1. rbobot
      08.08.2017 14:18
      -7

      удолил


    1. rumkin
      08.08.2017 14:39
      +3

      Хм… чтоб мы делали без вашего комментария!


    1. vsb
      08.08.2017 16:19
      +3

      Собственно проблема идентична проблеме запуска недоверенных программ и на сегодняшний день решить её не представляется возможным. Несмотря на все антивирусы и архитектурные усилия вирусы встречаются как на десктопе, так и на мобильных платформах. Нет никаких оснований предполагать, что в случае с npm, maven или любым другим менеджером пакетов что-то будет по-другому.


      1. lorc
        08.08.2017 19:14

        Ну когда вы ставите пакет через rpm/dpkg/apt/pacman/etc — вы уже уверены в его надежности? Потому что пакет подписан ключом мейнтейнера пакета, а ключ мейнтейнера подписан ключом дистрибутива.
        Ключ тяжелее украсть, чем аккаунт на популярном сайте.

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


        1. rumkin
          08.08.2017 20:31
          +2

          Почему сразу "никто не подумал когда создавал репозиторий", вы когда разрабатываете систему для двух с половиной человек тоже начинаете с сети доверия? Все хорошо работало, на энтузиазме и благих намерениях, но пришло время столкнуться с реальностью. Хотя, да, идея с сетями доверия выглядит своевременной.


        1. vsb
          08.08.2017 22:22

          > Ну когда вы ставите пакет через rpm/dpkg/apt/pacman/etc — вы уже уверены в его надежности? Потому что пакет подписан ключом мейнтейнера пакета, а ключ мейнтейнера подписан ключом дистрибутива. Ключ тяжелее украсть, чем аккаунт на популярном сайте.

          Ну это далеко не факт, что тяжелее. Уверен, что у 90% мейнтейнеров ключ лежит в обычном файле в ~/.gpg и украсть его не сложней, чем украсть пароль. Теоретически ключ лучше, потому что может лежать в железном девайсе, у которого нарушу торчит только API, но насколько эти теоретические преимущества используются на практике?

          Кстати подумайте, откуда мейнтейнеры берут исходники, с которых они собирают софт и чем отличается воровство github-пароля от воровства npm-пароля. Думаете, они проводят аудит каждого коммита?

          > Очевидно, что npm — не дистрибутив и поэтому владелец npm умается проверять каждого человека, желающего опубликовать свою библиотеку. Но и эта проблема решается сетями доверия.
          Просто об этом никто не подумал когда создавал репозиторий. И, кстати, с докером та же проблема.

          Вы правильно обозначили проблему. Мейтейнеров в дистрибутиве относительно немного. А сети доверия не работают. По крайней мере я пока не видел ни одного примера их практического применения. Тот же GPG уже лет 20 агитирует их. Давно вы были на вечеринке подписей?

          В любом случае никто не мешает сделать надстройку над npm, вести реестр доверенных пакетов и подписывать проверенные версии подписью мейнтейнеров. Думаю, что задача вполне выполнима, популярных пакетов не так уж и много, а обновляются они не так уж и часто. Крупным командам вроде Facebook, наверное, можно доверять по умолчанию. Сомневаюсь, что это кому-то надо, если честно, но может быть и будет такое.


          1. TheShock
            09.08.2017 04:19
            -1

            Уверен, что у 90% мейнтейнеров ключ лежит в обычном файле в ~/.gpg и украсть его не сложней, чем украсть пароль

            С другой стороны, тогда нужен и ключ и пароль к нему, а без ключа — только пароль. То есть ключ уже дает два фактора защиты (доступ к файлу и знание пароля) вместо одного

            Конечно, если владелец не хранит пароль рядом с ключом, а держит его в голове.


    1. varnav
      09.08.2017 16:05

  1. arthur_veber
    08.08.2017 14:18
    +5

    оффтоп: фото - огонь
    


  1. rumkin
    08.08.2017 14:44
    +5

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


    1. x07
      09.08.2017 08:55

      Надо сделать, так, чтобы код соответствовал коду на гитхабе, например сделать публикацию пакетов, таким образом, что бы они собирались из ветки мастер автоматом. Это спасёт от нечитаемого месива точно.


      1. vintage
        09.08.2017 09:15

        В пакетном менеджере DUB именно так и сделано. Чтобы выпустить новую версию пакета — достаточно добавить новый semver git tag. Это гораздо удобней, чем всякие npm (pre)publish.


    1. inook
      09.08.2017 09:44

      Всегда есть возможность посмотреть код пакета на github


      1. justboris
        09.08.2017 10:53

        То, что лежит на github может не соответствовать коду в npm. Надо руками скачивать с npm и проверять.


        Еще можно смотреть содержимое npm-пакетов через unpkg.com, но только если вы доверяете этому самому unpkg


  1. cbone
    08.08.2017 16:50
    +2

    Определение того, содержит ли пакет нечто вредоносное при публикации, конечно, эквивалентно приостановке работы, сделать мы этого не можем.

    Так проверяли бы не в момент публикации, а после. Если после проверки выяснится, что пакет безопасный — вешали бы шильдик «The package is safe.» А разработчик пусть сам решает, стоит рисковать и устанавливать ещё не проверенный пакет, или стоит подождать когда бот доберётся до него.


    1. k0ldbl00d
      08.08.2017 17:25
      +2

      Пользователь не всегда знает что он устанавливает. Если вы знакомы с разработкой на node, то и сами знаете почему.


      1. Fen1kz
        08.08.2017 17:53
        +2

        Если вы про зависимости, то просто циклически проверять шильдики.


        V This package itself is safe
        V This package and it's dependencies are safe.


    1. rumkin
      08.08.2017 18:26

      Вопрос в том, как бот будет проверять пакет? Что именно он будет искать? Мне кажется, что при автоматической проверке шильдик будет давать ложное чувство безопасности и в итоге сделает систему крайне уязвимой перед новыми атаками.


      1. springimport
        08.08.2017 22:16

        Мне кажется что можно особо тщательно проверять пакеты с каким-нибудь http.request.
        Хотя и можно создать 2 пакета: для отправки запросов (безопасный) и отправщик запросов.

        Идеального решения нет, но вопрос ввода шильдиков это вопрос времени, имхо.


        1. rumkin
          08.08.2017 22:26

          Есть еще компилируемые пакеты, а компанды npm могут содержать инструкции написаные на bash (т.е. потенциально инструкцию на любом языке). Cкрипт на JS может вызывать curl и т.п.


          Так что вариант со срабатыванием на определенный пакет, защитит от очень узкого класса атак. Шильдик должен использоваться не раньше, чем будет достигнут минимально допустимый уровень безопасности.


          1. springimport
            08.08.2017 22:41

            Для начала думаю будет как на утубе и в вк: самых популярных проверят и все. Разница в том что в случае менеджера пакетов нужно проверять постоянно. И в будущем когда вася будет ставить условный
            сrеssеnv он увидит что пакет левый и напишет в поддержку.


      1. doctorw
        09.08.2017 12:42

        Можно сбрасывать шильдик, при любом изменении пакета, так чтобы требовалась повторная проверка.


  1. mwizard
    08.08.2017 21:35
    +3

    эквивалентно приостановке работы
    equivalent to the halting problem

    Но это "проблема останова", а не "приостановка работы".


    1. rumkin
      08.08.2017 22:20

      1 к ~5К


  1. iit
    09.08.2017 06:56

    В apt/yum есть source list который указывает какой пакет из какой репы тянуть пока туда всякого бреда не добавить — все ок.


    В composer пакеты состоят из пары автор+пакет который не позволит без pull request человеку посередине как-либо заменить пакет без авторов. и пока вы доверяете автору и проверяете его пакеты — все ок.


    а тут — одна очепятка и вы труп.


    1. justboris
      09.08.2017 10:58
      +1

      Не очень понял как composer защищает от сквоттинга пакетов с опечатками в названии. Что мешает завести там пакет с именем "lavarel" например?


      1. iit
        09.08.2017 11:32

        имя пакета = имя автора/имя пакета


        в случае с laravel это laravel/laravel


        добавить свой пакет с laravel может любой но вот в вашем случае он будет выглядеть как justboris/laravel
        это немного решает проблему сквотинга.


        Да можно назвать пакеты lalavel/lalavel но тогда придется либо подделывать все его зависимости от автора laravel а их может быть довольно много. либо затягивать оригинальный пакет и самой папке vendor будет и laravel и lalavel что заставит задуматься адекватного разраба что он затянул что-то не то.


        Также такой подход позволяет строить более адекватную сеть доверия так как имя автора зашито в пакете и одновременно позволяет создать несколько одинаковых конкурирующих пакетов с одинаковым именем от разных авторов.


        1. justboris
          09.08.2017 11:43

          А вы действительно смотрите в папку vendor после установки зависимостей?


          Точно так же можно сказать и про node_modules, что, если заглянуть в нее, то там будет видно неправильное имя. Но, как правило, никто туда не смотрит.


          1. iit
            09.08.2017 12:41

            Как ни странно я понимаю почему туда никто не смотрит, для меня такого сурового backend php человека найти что-то в этой папке просто нереально. простейший проект содержит +100500 элементов.


            Если бы сгруппировать её как в composer хотя бы по авторам — думаю она была бы куда компактнее и просматривать её было бы куда удобнее. Еще обилие модулей из 1.5 файла и 50-100 строк вроде того-же скандального leftpad который любой backend человек напишет за 20 минут тоже играет свою роль.


            Возможно это просто вопрос религии но в php есть смысл создавать, поддерживать и использовать библиотеку только тогда когда функционал в ней "чуть сложнее" чем добавление 20 пробелов в начало строки.


            Что касается vendor то раз в неделю я там точно бываю (если это только не двух недельный отпуск)


            1. TheShock
              09.08.2017 13:31
              -1

              Как ни странно я понимаю почему туда никто не смотрит

              Вообще да, структура node_modules просто отвратительная, а вложенность зависимостей — крайне дурацкая идея. Я уж молчу, что иногда вложенность такая, что винда не может работать с этой директорией (например удалить ее). Конечно, это больше кривизна винды, чем ноды, но все-равно.


              1. justboris
                09.08.2017 14:41

                Так зависимости же складываются в плоский список, если это возможно. Если А и В зависят от С одной версии, то С попадет на один уровень с A и В.


                Или вы не об этом?


                1. iit
                  09.08.2017 15:09

                  Мы тут скорее о том что открыв node_modules в типичном проекте ты увидишь папку с +100500 папок внутри и по сути структура действительно плоская.


                  1 папка — 1 библиотека


                  пример:


                  • 7zip-bin
                  • 7zip-bin-linux
                  • ansi-align
                  • ansi-regex
                  • ansi-styles

                  в composer 2 уровня вложенности — автор/библиотека
                  пример:


                  • laravel/framwork
                  • laravel/passport
                  • symfony/console
                  • symfony/debug
                  • symfony/process
                  • symfony/routing
                  • symfony/yaml
                  • symfony/var-dumper

                  итог — вместо 8 папок под каждую библиотеку у нас 2 папки авторов с 2 и 6 библиотеками соответственно


                  В java это дошло до абсурда где папка библиотеки = домен.сайт.проект.автор.библиотека.модуль


                  Например в maven для того чтобы добраться до самого jar файла библиотеки нужно открыть 3-5 папок.


                  1. justboris
                    09.08.2017 15:11

                    Ваш аргумент я понял, и с ним я соглашусь. Но TheShock пишет:


                    а вложенность зависимостей — крайне дурацкая идея

                    Вот я и не понимаю, вложенность — это хорошо или плохо


                    1. iit
                      09.08.2017 15:26

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


                      теоретический лимит ntfs на папку — 4,294,967,295 файлов но на практике уже 10000 файлов вызывают дикие лаги на win7.


                      В ext4 который нет лимита на папку но есть лимит на количество файлов и папок в принципе и он огромен и в случае надобности его можно внезапно увеличить.


                      Плюс если папка разрослась до того что лагает в linux есть как минимум 5 способов её удалить но это очень редкая ситуация.


                      Сама по себе вложенность это не что-то плохое а скорее нечто с чем приходиться жить.


                    1. TheShock
                      09.08.2017 15:45
                      -1

                      Но TheShock пишет:

                      Я немного о другом. Вложенность зависимостей — дурацкая идея. Проблема в том, что " в плоский список, если это возможно". Почему-то, очень часто оно не работает. Может дело в зависимостях зависимостей? Я не знаю. Так вот — очень часто их глубина становится слишком большой. Проблема не с количеством файлов, а с тем, что путь к самым глубоким зависимостям такой длинный, что винда не может с ним работать.
                      Как на меня все модули должны всегда лежать на одной вложености (не важно какой, это может быть как iit предлагает), плюс я бы еще версию добавил, как раз, чтобы любой модуль мог подключить необходимую версию.

                      laravel/framwork/1.0
                      laravel/framwork/2.0
                      laravel/passport/0.1
                      symfony/console/1.0
                      symfony/console/1.2
                      symfony/debug/1.5
                      


                      1. ReklatsMasters
                        09.08.2017 19:58

                        такой длинный, что винда не может с ним работать

                        npm начиная ещё с v3 старается собирать зависимости в плоский список.


                        to iit


                        на практике уже 10000 файлов вызывают дикие лаги на win7

                        Расскажите, что это у вас за проект такой, в котором 10к зависимостей.


                        1. iit
                          09.08.2017 20:20

                          речь шла не о зависимосях а о файлах. а файлов куда больше 10.000 причем настолько что пришлось увеличивать лимиты inode на сервере. а проект — обычный финансовый портал внезапно на php и моднутой сумрачными гениями umi cms, естественно без composer а фронт на костылях jquery и scritpaculous.


                          файлы в основном изображения в новостях. новостей штук 15-20 в день и в каждой от одного до 15 изображений. с 2008 года набралось их очень приличное количество.


                          естественно при разворачивании папки с изображениями на win7 explorer.exe превращаеться в тыкву.


                          1. ReklatsMasters
                            10.08.2017 00:05

                            Увеличенные лимиты ноды на сервере это must have. Но я не понимаю, зачем вам таскать все изображения во время разработки? Запилите sub-repo и положите туда все картинки. С таким количеством файлов в папке и линукс в тыкву превратится. Например, однажды потребовалось удалить 10к папок внутри одной папки. Удалось только с помощью zip / gzip -m вроде, всё остальное тупо зависало.


                            1. iit
                              10.08.2017 05:25

                              Ну мы так по сути и сделали. таскать эту папу по сети.при git clone вообще невозможно было.


                        1. TheShock
                          09.08.2017 20:37
                          -2

                          npm начиная ещё с v3 старается собирать зависимости

                          То, что старается, а не собирает — это плохо.


                          1. ReklatsMasters
                            09.08.2017 23:54
                            +1

                            У вас в профиле написано что вы сеньор. Окей, приведите мне в пример либу / пакет, который установится не плоско, а по-старому. У вас ведь есть факты, иначе бы вы это не утверждали. https://stackoverflow.com/a/31315303/1556249


                            1. TheShock
                              10.08.2017 04:24
                              -1

                              Зачем «приводить либу», если в вашей же документации есть пример:

                              image

                              Или даже вот такая картинка:
                              image

                              То есть я, конечно, понимаю, что в версии 3 уже получше, чем в версии 2. И что там написано как уменьшить эти проблемы, но ведь можно было сделать лучше. Не «мы пытаемся выровнять, но иногда, конечно, какая-то либа может использоваться 3 раза», а именно сделать, чтобы вложенность всегда была одинаковой и чтобы двух копий одной версии вообще не могло появится.


                              1. justboris
                                10.08.2017 11:44

                                При require('module-name') node.js ищет именно папку module-name, и если там будет несколько версий, то как ему выбрать какую-нибудь из них?


                                Именно поэтому npm и yarn раскладывают модули по папкам, так чтобы в ближайших node_modules находились только правильные версии пакетов.


                                1. vintage
                                  10.08.2017 13:46

                                  Очевидно эту проблему не решить, без изменения поведения require.resolve.


  1. megahertz
    09.08.2017 08:36

    Ожидаемо. Вангую, что в один прекрасный день злоумышленники получат доступ к пакету вроде нашумевшего left-pad и выкатят зараженную версию. package-lock решает проблему, но только частично.