Недавно я получил электронное письмо от Github, в котором сообщалось об определенной уязвимости безопасности в одном из моих репозиториев.

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

Вышеупомянутое репо, ssr-response-app, было тестовым репо, которое я использовал, чтобы поиграть с Next.js и его реализацией рендеринга на стороне сервера. . Это было некоторое время назад. Поскольку в этой статье нет ни одного из них, я не буду вдаваться в подробности. Мы будем строго придерживаться обсуждаемой темы, проблема ниже.

В установленной версии js-yaml обнаружена известная уязвимость системы безопасности высокой степени серьезности.

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

Большинство из нас использует много кода, созданного другими разработчиками, в виде библиотек. Причины использования указанных библиотек различны - временные ограничения для создания индивидуального решения, ощущение того, что нет необходимости изобретать велосипед, простая оценка некоторых авторов библиотеки и так далее и так далее. Какой бы ни была причина, в процессе разработки программного обеспечения мы чаще всего втягиваем библиотеки в нашу кодовую базу. В среде Javascript, как в моем случае, пакеты извлекаются из NPM (диспетчера пакетов узлов).

NPM - это реестр тысяч пакетов, опубликованных разными авторами. Поскольку эти пакеты решают конкретную проблему, иногда они могут вносить уязвимости в код. Это может быть из самого пакета или зависимостей, которые он использует - мы называем это каскадными зависимостями. Например, установка Express, фреймворка для веб-приложений Node.js, устанавливает еще 40+ других пакетов, от которых он зависит! Безопасность - это серьезная проблема, особенно когда мы говорим о поставках программных продуктов в производство. Последствия того, что закрывать глаза, высоки.

Примеры уязвимостей могут варьироваться от проблем межсайтового скриптинга (на которые приходится более 80% всех проблем безопасности) до проблем с отказом в обслуживании, таких как блокировка цикла событий, нехватка памяти и атаки на безопасность регулярных выражений. Эти уязвимости безопасности могут привести к сбою серверов и краже данных.

Онлайн-сервисы, такие как Snyk, можно использовать для тестирования репозиториев Github, пакетов npm и образов докеров на наличие известных уязвимостей. Но в нашем случае мы сразу перейдем к терминалу и изучим команды npm audit и npm audit fix.

NPM Audit

NPM Audit используется для отслеживания и предоставления отчета об уязвимостях безопасности модулей npm, имеющихся в вашей среде. У каждой уязвимости есть уровень серьезности (низкий, средний, высокий, критический). Само собой разумеется, что проблемы, помеченные как «Высокий» или «Критический», необходимо решать немедленно. Обнаружив проблемы, NPM Audit дает вам возможность исправить их, обновив пакеты до опубликованной версии, в которой устранена выявленная проблема.

Вернемся к ssr-react-app. Ниже находится файл package.json. Обратите внимание на свойство dependencies.

Обнаруженный пакет js-yaml, о котором сообщил Github, отсутствует в зависимостях, указанных в нашем package.json! Странный? Мы скоро вернемся к этому.

Следующим шагом является переход к корню папки моего приложения и выполнение команды npm audit. Ниже приведены результаты.

Давайте рассмотрим это. У нас есть три обнаруженных уязвимости (2 средней и 1 высокой степени).

У каждой уязвимости есть уровень серьезности и Тип уязвимости, Имя пакета, Зависимость (который указывает, этот пакет является зависимостью другого установленного пакета) и столбца Дополнительная информация, в котором содержится ссылка с более подробной информацией о природе уязвимости. Я настоятельно рекомендую перейти по ссылке «Подробнее». Если мы стремимся решить проблему, мы должны сначала ее понять.

Вторая уязвимость, о которой сообщалось выше, - это js-yaml. Но если вы присмотритесь, то увидите, что это зависимость от zeit / next-css. Это результат каскадных зависимостей - мы упоминали об этом ранее.

Команда npm audit имеет флаг json, который выводит ту же информацию в формате JSON. Этот вывод можно при желании записать в файл.

Выходные данные JSON могут быть переданы в визуализатор или синтаксический анализатор, который извлекает общее количество проблем в нем во время процесса непрерывной интеграции (CI).

Выполнение команды npm audit fix пытается исправить эти уязвимости.

Итак, мы идем. Решено 3 проблемы из 3. Пакет axios обновлен с 0.18.0 до 0.19.0. Кроме того, были добавлены 3 пакета от 4 участников и 3 были обновлены. Похоже, что уязвимость устранилась. Но нигде нет упоминания о js-yaml. Действительно ли было обновление для него? Что ж, может показаться, что это не так, но быстрый git diff package-lock.json докажет обратное.

Это без сомнения доказывает, что пакет js-yaml действительно был обновлен с версии 3.12.2 до версии 3.13.1, в которой реализовано исправление уязвимости.

Семантическое управление версиями - это то, на что следует обратить внимание, когда дело доходит до выполнения команды npm audit fix. Если обновление представляет собой патч или дополнительную версию, то обновление происходит автоматически. Однако, если для обновления требуется переход на основную версию, необходимо передать флаг force. Будьте осторожны с этим флагом. В отличие от второстепенных версий и версий с исправлениями, которые имеют обратную совместимость, в основных версиях обычно есть критические изменения. Следовательно, обратитесь к документации пакета перед запуском команды.

Если вы просто хотите увидеть, что потенциально будет обновлено при запуске npm audit fix, не обязательно влияя на изменения, то флаг пробный запуск - это то, что вам нужно.

Команда fix также предлагает флаг only для нацеливания на пакеты среды, то есть dev или prod. Аргумент prod будет нацелен на пакеты в свойстве dependencies в файле package.json, а аргумент dev будет нацелен на devDependencies.

Что делать, если нет опубликованного исправления?

Иногда можно сообщить об определенных проблемах, но опубликованное исправление недоступно. В таком случае:

  1. Помогите сопровождающим пакета, обнаружив причину указанного риска и сообщив о нем, создав проблему. Вы даже можете пойти дальше и сделать Pull Request с вашим внедренным решением.
  2. Используйте разветвленную версию пакета и исправьте ее. Затем вы можете ссылаться на свою разветвленную версию в своем приложении.

Преимущества аудита НПМ

  1. Использует работу других участников сообщества разработчиков ПО с открытым исходным кодом.
  2. Проблемы четко обозначены и помечены степенью серьезности.
  3. Предлагает готовую возможность исправить обнаруженные уязвимости, если решение было опубликовано.

Подведение итогов

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

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

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