Transcript
00:00:00Если вы устанавливаете NPM-пакеты, вы — цель. Может, не сегодня, может, не на этой неделе, но это
00:00:05определенно произойдет. Только за последние несколько месяцев были скомпрометированы сотни пакетов,
00:00:09и поток не иссякает. Поэтому вместо того, чтобы беспокоиться каждый раз, когда это всплывает,
00:00:14я решил обезопасить свою настройку для NPM, PNPM и BUN, и оказалось, что большая часть
00:00:18того, что могла бы вас спасти, настраивается буквально за 30 секунд. Так что в этом видео
00:00:23я покажу семь изменений, которые я сделал: от одной строки в конфигурации, которая
00:00:27сразу пресекает самые частые атаки, до бесплатных инструментов, предложенных самими злоумышленниками,
00:00:30которые выявят угрозу еще до того, как пакет попадет на вашу машину. Поехали.
00:00:39Первый и самый простой совет: перестаньте скачивать новые пакеты. Большинство этих атак на
00:00:44цепочку поставок обнаруживаются в течение нескольких часов, поэтому если просто не устанавливать новые версии
00:00:48сразу после их выхода, вы фактически избежите большинства этих атак. Все основные менеджеры пакетов Node.js
00:00:52теперь предлагают некое ограничение по возрасту релиза. Для NPM это настраивается в файле .npmrc
00:00:57и задается в днях. Для PNPM это можно задать глобально в файле pnpm-config.yaml,
00:01:03или для конкретного проекта через файл pnpm-workspace, и это значение задается в минутах.
00:01:08Стоит отметить, что начиная с PNPM 11, по умолчанию установлено значение один день,
00:01:14так что даже если вы ничего не настроите, у вас уже есть некоторая защита. Для BUN это задается в файле
00:01:17bunfig.toml, глобально или для проекта, и здесь значение задается в секундах.
00:01:23Меня действительно удивляет, что для трех менеджеров пакетов мы имеем три разных единицы измерения для одной и той же настройки,
00:01:27это хорошо описывает текущую экосистему. Как только вы это настроите,
00:01:32если вы установите такой пакет, как tanstack react-start, он не установит версию
00:01:36сразу, а выберет последнюю, подходящую под мои критерии возраста релиза, которые у меня
00:01:41составляют одну неделю. Если вам нужно обойти это, например, из-за проблем с безопасностью в
00:01:45пакете, который вы устанавливаете, и вам нужна именно последняя версия, вы все равно можете это сделать
00:01:49через командную строку, но будьте осторожны с LLM, так как я видел случаи, когда модели
00:01:54использовали этот обход и все равно устанавливали последние версии. Еще один момент:
00:01:59npx и bunx не учитывают эту настройку, они всё равно устанавливают последнюю версию,
00:02:03и в BUN есть открытый PR, чтобы это исправить. Пока мы в настройках, давайте
00:02:07отключим установочные скрипты для NPM. В PNPM и BUN это поведение по умолчанию,
00:02:12так что там ничего настраивать не нужно. Если вы не знали: при установке пакета ему
00:02:16разрешено выполнять свой собственный код сразу после установки. Это было сделано для легитимных
00:02:20целей, вроде компиляции нативного кода или скачивания бинарников, но проблема в том, что почти каждая
00:02:26атака на цепочку поставок использовала этот метод для запуска вредоносного кода на вашей машине сразу после установки.
00:02:30Если вы нашли пакет, которому действительно нужны такие скрипты, вы можете явно их
00:02:34разрешить. В PNPM, когда вы устанавливаете пакет с post-install скриптами, он сообщит вам об этом,
00:02:39как в случае с esbuild, и вы сможете выполнить pnpm approved-builds, чтобы выбрать, какие разрешить,
00:02:44это меняет вашу конфигурацию pnpm workspace allow-builds, также можно использовать
00:02:48флаг allow-build при команде установки для того же результата. В BUN, как я сказал, установка скриптов
00:02:52также отключена по умолчанию, но стоит знать, что у него есть список одобренных
00:02:56пакетов, которым разрешено выполнять эти скрипты, включая те, что я установил, например,
00:03:00esbuild. Вы можете отказаться от этого, добавив trusted-dependencies в ваш package.json,
00:03:04таким образом, только явно разрешенные пакеты смогут запускать post-install скрипты.
00:03:09Также сказано, что если установить пустой массив, он должен переопределить этот список по умолчанию,
00:03:12но, похоже, у меня это не работает, и я нашел баг на GitHub.
00:03:17Временное решение сейчас — просто добавить одно значение в список, и тогда список по умолчанию
00:03:21игнорируется. В BUN вы также можете запустить bun pm untrusted, чтобы увидеть, какие пакеты хотят выполнять
00:03:26скрипты, но еще не доверенные, а затем запустить bun pm trust, чтобы разрешить один из них, или просто добавить его в массив
00:03:30trusted-dependencies. Вы можете полностью отключить скрипты в BUN, установив install-scripts в
00:03:35false в глобальном конфиге bunfig. Для NPM это сложнее. Честно говоря, просто не используйте
00:03:40NPM, используйте PNPM, но если вы все-таки должны использовать NPM, вы можете получить похожий белый список,
00:03:45используя пакет Lavamote allow-scripts. Таким образом, это будет белый список прямо в вашем
00:03:50package.json. Третий совет — блокировать git-зависимости. В NPM зависимость может
00:03:55быть объявлена как git-ссылка, что обходит реестр, и может даже поставляться со своим .npmrc, который
00:04:01включает обратно жизненные циклы скриптов. Это один из трюков, использованных в недавней атаке на цепочку поставок,
00:04:05которая затронула tanstack. Вы можете остановить это, установив allow-git в none в вашем конфиге NPM,
00:04:10что блокирует их полностью, а другой вариант — установить в root, что позволяет устанавливать
00:04:15git-зависимости, только если они объявлены в вашем корневом package.json, так что, скорее всего,
00:04:19явно вами. Для PNPM есть опция block-exotic-sub-dependencies. Когда установлено в true,
00:04:25только прямые зависимости, то есть те, что вы перечислили в корневом package.json, могут использовать экзотические
00:04:29источники, такие как git-репозитории или прямые URL на файлы. В Bun этой опции пока нет, но
00:04:35есть PR, чтобы добавить ее, так что, возможно, скоро увидим. В качестве бонуса к советам по настройке
00:04:40PNPM имеет настройку trust-policy, которую можно установить в no-downgrade, это означает,
00:04:45что PNPM выдаст ошибку, если уровень доверия пакета снизился по сравнению с предыдущим релизом. Если
00:04:50пакет ранее был опубликован доверенным издателем, а теперь у него только проверка подлинности или
00:04:55вообще нет подтверждений доверия, установка завершится ошибкой. Это должно помочь поймать атаки, которые находят способы
00:05:00обойти обычные процессы публикации. Четвертый совет, вероятно, самый мощный: используйте
00:05:04инструмент, который анализирует устанавливаемые пакеты и может проверять их до того,
00:05:08как они коснутся вашего компьютера. Для этого есть два мощных и бесплатных инструмента. Первый —
00:05:14NPQ. Вы можете настроить его, создав псевдоним для обычных команд NPM, PNPM или Bun,
00:05:18чтобы при каждой установке он проверял несколько вещей. Он сканирует на известные
00:05:23уязвимости в базе данных Snyk и помечает пакеты, которым менее 22 дней. Он
00:05:28выявляет тайпосквоттинг, когда кто-то публикует пакет, например, express с двумя s, надеясь,
00:05:32что вы ошибетесь при вводе и установите не то. Он проверит подпись реестра и
00:05:37происхождение сборки. Предупредит, если у пакета есть pre- или post-install скрипты. Кроме того,
00:05:41он проверяет такие базовые вещи, как количество скачиваний, наличие README, лицензии, URL репозитория,
00:05:46и e-mail автора, и зарегистрирован ли домен. Он делает все это
00:05:51и выдает интерактивный отчет о ваших пакетах, где вы можете решить, хотите ли вы
00:05:55его устанавливать. Второй — Socket Firewall. Это тот, который использую я,
00:05:59и опять же, вы создаете псевдоним для ваших менеджеров пакетов, он поддерживает
00:06:03даже не только JavaScript, но и Python, и Rust. Подобно NPQ, при запуске установки
00:06:08он проверяет пакеты и блокирует подтвержденные вредоносные, а также предупреждает
00:06:12об угрозах, обнаруженных ИИ, которые еще не были просмотрены людьми. Честно говоря,
00:06:16я выбрал Socket Firewall, так как услышал о нем первым, и я доверяю Socket, так как они
00:06:21поймали много вредоносных пакетов, и злоумышленники даже давали интервью, где сказали,
00:06:25что Socket обнаруживает вредоносное ПО еще до того, как оно доберется до машины, что отличная
00:06:30реклама для них, и мне нравится, что он поддерживает больше, чем JavaScript, с UV, pip и cargo.
00:06:35Если вы установите один из них, обязательно очистите кэш вашего менеджера
00:06:38пакетов, чтобы убедиться, что каждый пакет проверяется файерволом. Пятый совет — про
00:06:42lock-файлы. В них записан реальный URL скачивания для каждого пакета, и проблема в том,
00:06:47что почти никто не проверяет lock-файлы в PR. Поэтому если кто-то делает PR в ваш
00:06:51репозиторий, он может тихо изменить разрешенный URL на пакет, который он контролирует, и также установить
00:06:56соответствующий хеш целостности, чтобы ничего не выглядело подозрительно. В следующий раз, когда вы сделаете установку, вы скачаете
00:07:01код с сервера атакующего. Хорошая новость: если вы используете PNPM, вы не уязвимы
00:07:05к этому. Он не хранит эти источники, которые можно подменить, и также не установит
00:07:09ничего, что есть в lock-файле, но не объявлено в вашем package.json. Я не нашел
00:07:14конкретной информации по Bun, так что он может быть уязвим. Если вы не
00:07:18используете PNPM, используйте инструмент под названием lockfileLint. Установите его как dev-зависимость, он проверяет
00:07:23ваш lock-файл, сверяя каждый пакет с доверенным хостом, например, реестром NPM. Он проверяет,
00:07:28совпадают ли разрешенные URL с именем пакета, а также проверяет, настоящие ли хеши целостности.
00:07:32Если он подозревает, что что-то было подделано, установка завершится ошибкой. Шестой совет — перестаньте
00:07:37использовать NPM install в CI и продакшене, вместо этого используйте «чистую» установку. Команда для этого в NPM —
00:07:42npm ci, а для Bun и PNPM вы добавляете флаг frozen-lockfile, хотя у них тоже есть CI
00:07:47команды, которые делают то же самое. PNPM использует это по умолчанию, если обнаруживает,
00:07:52что работает в среде CI. Команда clean install устанавливает точно то, что находится в lock-файле,
00:07:57ничего больше, и если lock-файл и package.json не согласованы, он останавливается и выдает ошибку,
00:08:01вместо того чтобы угадывать и устанавливать что-то другое. Это должно предотвратить подмену версии
00:08:05злоумышленником. Ничего из этого не работает, если вы не коммитите свой lock-файл в
00:08:09первую очередь, так что убедитесь, что он в системе контроля версий, а не в gitignore. Признаюсь, когда я
00:08:13только начинал программировать, я думал, что их нужно игнорировать, поэтому я рад,
00:08:17что научился их коммитить. Эти шесть советов касались конфигурации и инструментов, но есть и
00:08:21привычки, которые помогут вам избежать атак. Первая — перестаньте слепо обновлять
00:08:25все подряд. Вы, возможно, запускали npm update или другие версии этой команды, и просто
00:08:30обновляли каждую зависимость до последней версии за раз, но именно на такое поведение надеются
00:08:35злоумышленники, поэтому просматривайте эти обновления и спрашивайте себя, зачем вам нужно
00:08:39обновлять это. Вторая привычка становится все более актуальной: используйте меньше пакетов. Каждая
00:08:43добавленная зависимость — это еще одна поверхность атаки, и большинство этих атак распространяются через зависимости
00:08:48зависимостей, так что стоит задаться вопросом, почему вам нужна эта библиотека. Примеры, которые я вижу:
00:08:53Lodash для функций, которые можно сделать небольшим фрагментом кода, или Axios, когда
00:08:58fetch может делать то же самое. Причина, по которой я говорю, что это актуально — в эру агентного
00:09:03кодинга довольно легко заставить ИИ написать несколько функций вместо использования зависимости.
00:09:08Третья привычка — закрепление зависимостей на точной версии, так что обновление — всегда
00:09:12осознанный выбор. Но знайте, что это блокирует только те пакеты, которые вы выбираете в package.json,
00:09:17а зависимости ваших зависимостей все еще могут использовать свои диапазоны, поэтому тот
00:09:21период ожидания из совета №1 важен. Все это вместе должно дать вам спокойствие, что вы не
00:09:25случайно установите скомпрометированный пакет. Они не делают вас неуязвимыми, но они намного лучше, чем
00:09:29ничего. Итоговый совет — запускать всё в изолированном dev-контейнере, но мне всегда казалось,
00:09:34что это хлопотно, поэтому я возвращаюсь к локальной разработке. Если вы знаете другие способы
00:09:38защитить себя от атак такого типа, дайте знать в комментариях ниже, а пока вы там,
00:09:42подписывайтесь, и как всегда, увидимся в следующем видео.
Community Posts
No posts yet. Be the first to write about this video!
Write about this video