Как превратить данные об уязвимостях в продукт для принятия мер: от списков алертов к очередям исправлений
API данных об уязвимостях дают лишь кандидатов на риски. В статье разбираем, как объединить активы, область зависимостей, достижимость, эксплуатацию в реальных атаках и версии с исправлениями, чтобы превратить алерты безопасности в выполнимые и закрываемые инженерные задачи.
Отправить список зависимостей в API данных об уязвимостях и получить пачку CVE или бюллетеней безопасности — ещё не значит построить продукт для управления уязвимостями. Командам разработки на самом деле нужна рабочая очередь: какой сервис затронут, почему проблему нужно устранить сейчас, кто будет вносить изменения, что сломается при обновлении и как доказать, что риск закрыт.
Обсуждения на Hacker News по ссылке https://news.ycombinator.com/item?id=47094192 касаются шума в алертах, достижимости вызовов и перекладывания задач безопасности на разработчиков. Комментарии не отражают консенсус отрасли, но напоминают тем, кто проектирует продукты: если каждое сканирование лишь увеличивает красные цифры, не давая достаточно контекста для действий, пользователи в итоге перестанут обращать внимание на весь канал.
Записи об уязвимостях — лишь кандидаты; задачи определяет контекст активов
База уязвимостей указывает, что определённые версии пакета затронуты. Внутри организации нужно выяснить: присутствует ли эта версия в текущей сборке, в каком окружении развёрнут пакет, доступен ли он извне, может ли выполнение дойти до уязвимой функции и доступны ли уже патчи или практически применимые меры по снижению риска? Уровень критичности — лишь один из факторов.
API по адресу https://google.github.io/osv.dev/api/ поддерживает запросы по версии пакета или коммиту, а также пакетные запросы и чтение записей об уязвимостях по ID. Это подходит для сопоставления ведомостей состава ПО (SBOM) с публичными записями об уязвимостях, но одних результатов запроса недостаточно, чтобы доказать подверженность продакшен-среды риску. Lock-файлы, артефакты сборки, образы контейнеров и запущенные экземпляры могут расходиться, поэтому нужно чётко указывать, что именно сканировалось.
Для каждого кандидата сначала нужно установить связь с конкретным активом: репозиторий, компонент, фактически используемая версия, идентификатор сборки, окружение развёртывания и ответственный. Если доступны только данные о зависимостях из ветки по умолчанию, ограничьте вывод этой веткой и не расширяйте его до утверждения, что в продакшен-системе есть уязвимости. Если статус развёртывания определить нельзя, задачей должен стать сбор недостающих подтверждений об активе, а не создание ложной определённости.
При объединении данных из нескольких источников сохраняйте происхождение каждого из них
На странице https://google.github.io/osv.dev/data/ перечислены охваченные экосистемы и базы-источники. Одна уязвимость может быть описана несколькими источниками, а записи о ней позднее могут быть исправлены, отозваны или дополнены диапазонами затронутых версий. Продукт может показывать объединённое представление по алиасам и координатам пакетов, но обязан сохранять ID каждого источника, время обновления, затронутый диапазон и ссылку на оригинал.
Несколько источников не удваивают достоверность автоматически. Несколько сайтов могут перепубликовать один и тот же бюллетень, а несколько баз — использовать одну и ту же исходную запись. По-настоящему полезная перекрёстная проверка сравнивает, подтверждают ли источники независимо одни и те же ключевые поля: затронутые версии, версии с исправлением, предусловия эксплуатации или статус отзыва. Противоречащие поля нужно явно показывать, а не позволять модели молча выбрать одно из значений.
Стандартизированный объект может включать следующие части:
- Основные идентификаторы уязвимости, алиасы, затронутые пакеты и диапазоны версий.
- Исходные записи, время первого обнаружения и последней проверки, статус пересмотра или отзыва.
- Известные версии с исправлениями, меры смягчения от вендора и условия их применимости.
- Внутренние активы, окружения, зависимости и временные метки подтверждений, сопоставленные внутри организации.
- Сигналы приоритета, ручные оценки, ответственные и статусы обработки.
Так, даже если внешние описания изменятся, команда будет знать, на чём основывалось прежнее решение, а не видеть только текущую перезаписанную запись.
Приоритет — не просто сортировка по убыванию CVSS
Документация GitHub по Dependabot объясняет, что приоритет в нём учитывает такие сигналы, как CVSS, область зависимости и обнаружение вызовов уязвимых функций. Это показывает важный принцип: критичность, релевантность и практическую применимость нужно учитывать вместе, а не ограничиваться одной оценкой.
Каталог CISA Known Exploited Vulnerabilities используется для пометки уязвимостей, которые, как известно, эксплуатируются в реальных атаках, и рекомендуется как источник данных для моделей приоритизации при управлении уязвимостями. Совпадение с KEV требует повышенного внимания, но само по себе не доказывает, что организацию атаковали, и не заменяет оценку подверженности активов этой уязвимости.
Объяснимый приоритет может последовательно отвечать на следующие вопросы:
- Развёрнут ли актив и в каком окружении он находится: продакшен, внутреннее окружение или среда разработки.
- Является ли уязвимый компонент прямой или транзитивной зависимостью и попадает ли он в итоговый артефакт.
- Могут ли внешние или низкопривилегированные пользователи добраться до соответствующих точек входа и может ли выполниться уязвимый код.
- Известны ли случаи эксплуатации в реальных атаках, есть ли публичные меры смягчения и доступные версии с исправлениями.
- Каковы стоимость обновления и риски совместимости и какие временные окна допустимы для бизнеса.
Продуктам не нужно сводить эти вопросы к загадочной оценке риска от ИИ. Часто полезнее показывать доказательства и пробелы, например: «наличие в продакшен-образе подтверждено; внешняя доступность не подтверждена; есть версия с исправлением; тестирование обновления ещё не начато». Владельцы сразу видят, какие доказательства нужно предоставить дальше.
У очередей исправлений должны быть условия закрытия
Во многих панелях безопасности есть лишь три слишком общих статуса: «Открыто», «Отклонено» и «Исправлено», которые не отражают реальные инженерные процессы. В более практичных очередях могут быть такие статусы: «ожидает подтверждения актива», «подтверждено, что актив затронут», «исправление запланировано», «проверка изменений», «применены меры снижения риска, ожидается обновление», «закрыто», «несоответствие» и «риск принят». У каждого статуса должны быть условия входа и выхода.
Обновлённая версия ещё не означает закрытия. Проверка должна как минимум подтвердить, что новые lock-файлы или артефакты сборки больше не попадают в уязвимый диапазон, связанные тесты проходят, а в целевых окружениях действительно работают новые артефакты. Если применяются меры смягчения через конфигурацию, фиксируйте источник, условия применимости, срок действия и ответственного за итоговое обновление, чтобы временные решения не стали постоянными.
Игнорирование оповещений тоже требует обоснования. Тестовые фикстуры, которые не попадают в артефакты, ошибочно определённая экосистема пакетов или наличие уязвимости только в выведенных из эксплуатации ветках могут быть обоснованными причинами закрытия; «сейчас нет времени» к таким доказательствам не относится. Продукт должен позволять повторно открывать задачи, потому что записи как об активах, так и об уязвимостях могут меняться.
Наш ⟦анализ расхождений между рабочими возможностями и документацией](https://everyinfra.com/build/live-capability-catalog) объясняет, что декларации, конфигурации и фактическое поведение во время выполнения нельзя смешивать. ⟦Руководство по возвратам средств при сбоях и сверке](https://everyinfra.com/build/failure-refund-reconciliation) посвящено биллингу, но описывает не менее важный принцип ведения журнала событий: для каждого изменения состояния должна прослеживаться связь с его причиной, входными данными и последующими действиями.
Оповещения должны попадать в рабочую очередь владельца, а не во входящие всех сотрудников
Одна и та же уязвимость может затронуть десятки репозиториев, но для исправления иногда достаточно обновить общий базовый образ, а иногда каждый сервис нужно проверять отдельно. Объединяйте задачи до отправки уведомлений: создавайте основные задачи по общей первопричине, а затем подзадачи для затронутых активов. Иначе дублирующиеся сообщения создают мнимую нагрузку.
Отправляемое сообщение должно содержать сведения об активе, версии и окружении, обоснование приоритета, информацию о том, с чего начать исправление или снижение риска, недостающие доказательства и назначенного ответственного. Если ответственного нет, система должна показывать статус «не назначено», а не рассылать оповещение всей инженерной организации. Экстренные каналы используются только для событий, отвечающих заранее определённым условиям; остальные попадают в ежедневные очереди.
О сбоях повторного сканирования тоже нужно сообщать явно. Если источники данных об уязвимостях недоступны или формирование спецификации компонентов прервалось, зелёное сообщение «новых уязвимостей нет» опасно вводит в заблуждение. Как описано в нашем ⟦руководстве по ошибкам API и самовосстановлению](https://everyinfra.com/build/api-errors-self-healing), завершённое, частично завершённое и невыполненное сканирование должны быть разными состояниями.
Монетизацию можно строить на снижении затрат на доведение задач до закрытия, а не на продаже большего числа оповещений
На раннем этапе сервис может подключать ограниченное число репозиториев и окружений развёртывания одной инженерной команды, а люди участвуют в разборе несовпадений, привязке активов и проверке обновлений. Единицы тарификации можно строить вокруг управляемых активов, глубины рабочих процессов и совместной работы над реагированием, а не брать плату за каждую найденную уязвимость. Больше оповещений не значит больше ценности для клиента.
В пилотах фиксируйте время от кандидата до подтверждения, долю неназначенных задач, долю объединённых дубликатов, время закрытия после перехода к исправлению, причины повторного открытия и просроченные решения о принятии риска. Не ограничивайтесь показом того, что число обнаруженных уязвимостей снизилось: оно может падать и из-за сбоев сканирования, пропущенных активов или небрежного игнорирования.
Решения о продлении должны опираться на инженерные результаты: быстрее ли владельцы понимают риски, стало ли меньше дублирующих исследований, оставляет ли исправление проверяемые доказательства и вовремя ли обнаруживаются перерывы в покрытии. В статье рассматриваются подходы к созданию продуктов на основе данных об уязвимостях; она не подразумевает, что EveryInfra предоставляет услуги управления уязвимостями, и не содержит выводов о безопасности конкретных систем.
Данные об уязвимостях составляют слой публичной информации, а настоящая ценность продукта создаётся внутри организаций: внешние записи связываются с реальными активами, риски превращаются в выполнимые задачи, а задачи закрываются на основе доказательств из сборки, развёртывания и среды выполнения. Без этого даже самая полная база уязвимостей лишь удлиняет списки дел.
Справка BL-15