Привет всем 👋

Это моя первая статья на медиуме и я чувствую себя 👶 играющим в новую игрушку. Идея написать была у меня в голове год назад, но я не был достаточно уверен, чтобы начать писать… может быть, синдром самозванца? наверное да 🙈

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

На прошлой неделе я изо всех сил пытался исправить некоторые уязвимости npm, и я решил объяснить остальной команде, как я исправил и что из этого узнал. Это сработало в моем мозгу, о! может быть, это лучшая возможность написать что-то из своего опыта, что-то полезное.

Поэтому я решил написать эту статью 📝

Цель этой статьи – предоставить обходной путь, а не идеальное и четкое решение, поскольку существует множество различных вариантов использования, которые можно обрабатывать по-разному. Любые комментарии/отзывы очень приветствуются!

Контекст

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

В большинстве проектов, над которыми мы работаем, у нас есть куча сторонних библиотек в нашем package.json.

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

⚠️Проблема

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

Вот почему исправление и обнаружение уязвимостей в нашем проекте — это то, что мы должны поставить на первое место в списке наших приоритетов☝️.

🕵️‍♀️ Как обнаружить уязвимости риска npm

У нас есть несколько способов обнаружения уязвимостей, давайте рассмотрим некоторые из них:

1- аудит нпм 🔍

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

документация npm говорит:

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

Но некоторые уязвимости не могут быть исправлены автоматически и потребуют ручного вмешательства или проверки.



2. Безопасность Github/​​Оповещения Dependabot🤖

Возможно, вам знакомо это предупреждение, если ваш проект находится на Github:

GitHub Enterprise Server отправляет оповещения Dependabot при обнаружении уязвимостей, затрагивающих ваш репозиторий.



Действия по устранению этих уязвимостей

1- Старайтесь обновлять свои зависимости до последней версии ✅.

Это гарантирует, что вы используете последнее исправление/патч, если оно существует.

Существуют разные способы обновления ваших библиотек.

Один из способов — выполнить npm update, если ваше приложение готово обновить все библиотеки до последней версии:

https://docs.npmjs.com/cli-commands/update.html

Другой способ — использовать зависимого бота 🤖 в github, который инициирует запросы на извлечение, чтобы поддерживать настроенные вами зависимости в актуальном состоянии. Это мой любимый метод, так как он не ручной, и бот позаботится об этом.

2- исправление аудита npm

npm audit fix only изменяет зависимости, которые не должны вызывать проблем на основе правил SEMVER. Это будет первым шагом в устранении некоторых уязвимостей.

Но, к сожалению, многие уязвимости, которые вы можете найти в своем проекте, не могут быть исправлены этими методами.

3. В остальном это были шаги, которые я выполнил, чтобы исправить уязвимость.

Я искал известное решение и не нашел четкого списка шагов, поэтому я решил использовать логику для исправления.

Представьте, что у нас есть предупреждение об уязвимости в библиотеке «library1».

(*1*) У нас есть патч для неиспользуемой напрямую библиотеки1

У нас есть патч для «библиотеки1» (представьте, что это 4.2.1)

1- Добавьте этот код в раздел скриптов package.json (если у вас его еще нет):

Документация npm говорит:

Этот пакет изменяет package-lock.json, чтобы принудительно установить конкретную версию транзитивной зависимости (зависимости от зависимости).

⛔️ ВНИМАНИЕ:

Вариант использования для этого — когда есть уязвимость безопасности, и вы ДОЛЖНЫ обновить вложенную зависимость, иначе ваш проект будет уязвим. Но это следует использовать только в качестве последнего ресурса, вы должны сначала обновить свои зависимости верхнего уровня и зарегистрировать проблему для них, чтобы обновить уязвимые подзависимости.

И это наш случай ✅. Поскольку наша уязвимость не на высшем уровне, так что продолжим!

2- Затем добавьте этот новый раздел (если у вас его еще нет), а затем добавьте следующую строку кода:

«Force Resolutions» принудительно установит этот раздел разрешений перед остальными установками.

3- Теперь выполните npm ciсо своего терминала, и вы увидите, что уязвимость исчезла! 🎉

(*2*) У нас нет патча для библиотеки, которая не используется напрямую1

1- Выполните npm list library1 со своего терминала, чтобы увидеть дерево зависимостей.

Эта команда выведет список всех версий установленных пакетов, а также их зависимостей.

Вы увидите что-то вроде этого:

На этом древовидном графике вы можете увидеть, как библиотека1 используется из lib7 и из lib8.

Возможно, вы думаете об этом «обработанном» слове, которое появляется в этом дереве. deduped — это сокращение от «дедуплицированный».

В документации npm сказано, что npm dedupe :

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

2- Итак, на данный момент мы можем использовать разные стратегии.

Мой выбор состоял в том, чтобы попытаться обновить библиотеку в этом дереве сверху вниз с выпуском, который исправляет эту зависимость. Итак, найдите выпуск одной из этих библиотек в дереве зависимостей, в котором не используется эта неисправимая library1 .

Затем добавьте это в раздел разрешений. Выполните npm ci и вы увидите, как ушла ваша уязвимость! 🎉

Но может случиться так, что для этих библиотек нет патча, избегающего использования library1 , и тогда мы должны начать думать об изменении нашего кода, чтобы избежать использования «библиотеки верхнего уровня» в этом дереве зависимостей (в данном случае lib2 ).

Последний чек ☝️

Подождите ⛔️, даже выполнения всех этих шагов недостаточно, чтобы выпустить это изменение…

После того, как вы устранили уязвимость (это означает, что вы выполнили аудит npm и предупреждение исчезло), вы должны проверить, правильно ли работает ваше приложение. Потому что, возможно, некоторые пакеты несовместимы с последней версией и могут сломать ваше приложение.

Следите за обновлениями 🔎

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

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

Выводы

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

И, наконец, похлопайте этой статье, если она оказалась вам полезной, и спасибо за прочтение 🥰!