coscio/blog/sicurezza
Sicurezza26 luglio 2026· 7 min

CVE-сканирование зависимостей: с чего начать, если раньше этим никто не занимался

В типовом проекте на Node.js или PHP — сотни зависимостей, и вы не писали ни одной из них. Разбираем, как начать сканировать уязвимости так, чтобы не утонуть в сотнях предупреждений: что такое CVE и CVSS на практике, какие уязвимости реально опасны, как отличить настоящую проблему от шума и куда встроить проверку.

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

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

Разберём, как начать заниматься этим системно, если раньше не занимались.

Что такое CVE и почему номер сам по себе ничего не значит

CVE — это идентификатор конкретной уязвимости в публичном каталоге, вида CVE-2025-12345. Он не описывает опасность, он лишь означает: «такая проблема зарегистрирована и вот её описание».

Рядом обычно идёт оценка CVSS — число от нуля до десяти. Девять и выше принято называть критическим, семь-восемь — высоким, четыре-шесть — средним. Эта шкала полезна для сортировки, но абсолютно бесполезна как единственный критерий для действия, и вот почему.

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

Отсюда первое практическое правило: сканер даёт список кандидатов, приоритет расставляете вы.

Первый запуск: приготовьтесь к плохим новостям

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

Здесь есть развилка, и большинство команд выбирают неверную ветку: пугаются, решают «разберёмся, когда будет время», и не возвращаются к этому никогда. Правильная ветка — принять, что разгрести всё сразу невозможно, и начать с фильтрации.

Первый фильтр — среда выполнения. Разделите зависимости на те, что попадают в продакшен, и те, что живут только в разработке и сборке: линтеры, тестовые фреймворки, сборщики. Уязвимость в dev-зависимости почти всегда терпит: чтобы её эксплуатировать, нужно уже иметь доступ к вашей машине или к пайплайну. Это сразу срезает половину списка.

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

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

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

Транзитивные зависимости: главная головная боль

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

Здесь есть три сценария.

Лучший: авторы вашей прямой зависимости уже выпустили обновление, которое тянет исправленную версию. Обновляете верхний пакет — проблема уходит.

Средний: обновления нет, но менеджер пакетов позволяет принудительно поднять версию вложенной зависимости. В npm это resolutions или overrides, в других экосистемах есть аналоги. Работает, но требует проверки: вы меняете версию библиотеки в обход её потребителя, и совместимость никто не гарантировал.

Худший: библиотека заброшена, обновления не будет. Тогда варианты — заменить зависимость, форкнуть и пропатчить самому, либо принять риск сознательно, задокументировав это решение. Последнее — совершенно легитимный вариант, если риск оценён. Нелегитимно — не заметить проблему вовсе.

Что сканировать, кроме кода приложения

Зависимости приложения — только первый слой. На практике уязвимости приходят ещё из трёх мест.

Системные пакеты на серверах. Ядро, openssl, системные библиотеки, веб-сервер. Здесь всё проще: обновления выходят регулярно, ставятся штатным менеджером пакетов, и половина проблем закрывается автоматическими обновлениями безопасности. Стоит только помнить, что часть обновлений требует перезапуска сервисов, а некоторые — перезагрузки. Обновлённый пакет openssl на диске при работающем старом процессе в памяти — это по-прежнему уязвимый сервис.

Образы контейнеров. Базовый образ, собранный полгода назад, содержит все уязвимости, накопившиеся с тех пор. Это самая частая находка при первом сканировании инфраструктуры: приложение свежее, а под ним слой системных библиотек годовалой давности.

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

Как встроить это в работу, чтобы не забросить через месяц

Разовое сканирование бесполезно: через две недели картина изменится. Нужен процесс, и он должен быть максимально дешёвым в поддержке.

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

Второе место — регулярное сканирование того, что уже работает. Это принципиально другая проверка: код не менялся, а уязвимости появились, потому что о них стало известно. Раз в сутки достаточно.

Третье — реакция. У находки должен быть владелец и срок. Простая матрица: критические в продакшене — сегодня, высокие — на этой неделе, остальные — в ближайший плановый цикл обновлений. Без сроков список превращается в вечнозелёный бэклог, куда никто не смотрит.

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

Про SBOM

Термин SBOM — это просто список всего, из чего состоит ваш продукт, в машиночитаемом формате. Звучит бюрократически, но у него есть очень практическая ценность.

Когда выходит громкая уязвимость в популярной библиотеке — как это было с Log4Shell, — первый вопрос звучит так: «она у нас вообще есть?». Без SBOM ответ занимает от нескольких часов до нескольких дней и включает ручной обход всех проектов. С SBOM — это поиск по списку за минуту.

Собирать его отдельно не нужно: инструменты сканирования формируют его попутно. Достаточно просто сохранять результат при каждом релизе.

Как это сделано у нас

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

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

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

Что сделать на этой неделе

Запустите сканирование на одном, самом важном проекте. Не на всех сразу — на одном.

Отфильтруйте результат: уберите dev-зависимости, оставьте то, что действительно попадает в продакшен. Посмотрите на оставшееся и найдите те находки, для которых существует публичный эксплойт. Скорее всего, их будет немного — вот с них и начните.

Затем добавьте проверку в сборку и поставьте ежедневное сканирование. И запишите на одну страницу, кто смотрит на результаты и в какие сроки реагирует.

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

CO
COSCIO
Coscio team

Related posts

All posts
Sicurezza14 marzo 2026

Безопасность инфраструктуры в едином портале: сканирование зависимостей, мониторинг угроз, реагирование на брут-форс и интеграция с SIEM

Безопасность инфраструктуры небольшой компании держится не на одном файрволле, а на нескольких независимых слоях, каждый из которых решает свою задачу. Сканирование зависимостей, аудит открытых портов, обнаружение брут-форса, автоматическое реагирование и compliance-проверки — пять задач, которые в COSCIO собраны в один портал. Эта статья разбирает, как именно устроен раздел Security в COSCIO,…

Sicurezza14 marzo 2026

Просроченные SSL — невидимый источник даунтайма: как автоматизировать контроль сертификатов через единый портал инфраструктуры

SSL-сертификат — это та часть инфраструктуры, про которую вспоминают только тогда, когда она перестаёт работать. Утром в понедельник клиенты вместо сайта видят красное окно браузера "Подключение не защищено", и оказывается, что certbot на одном из серверов давно сломан, а никто этого не заметил. В статье разбирается, почему классический "поставил и забыл" с SSL не работает в инфраструктуре из…

Мониторинг14 marzo 2026

Цена даунтайма и работа со временем восстановления: метрики MTTR/MTBF, организация инцидентного потока, ChatOps и публичные статус-страницы

Даунтайм — это не только потерянная выручка за часы простоя. Это разорванные SLA, штрафы, отток клиентов и медленная эрозия доверия, которую невозможно посчитать в моменте. Эта статья — про то, как измерять время восстановления честно, почему интуиция врёт про "у нас всё стабильно", откуда берётся длинный MTTR в средних компаниях и как организовать инцидентный поток так, чтобы реагировать на…