Как читать авторский курс и нормативные материалы
Это учебные материалы, а не заключение о соответствии конкретного продукта. Организационные модели курса отделяйте от терминов стандарта: ППК в опубликованном проекте — машиночитаемый перечень, а живой реестр его версий является практикой сопровождения. Термин OSA в разных материалах имеет разный охват. Статус и обязательность нормативного документа проверяются отдельно; проект КАПО опубликован как проект первой редакции.
Конспект: поиск уязвимостей и управление VDR/VEX
Зачем модуль
SBOM — это инвентарь, а не отчёт о безопасности. Сам файл cyclonedx.json не знает ни про одну CVE: уязвимости возникают, когда координаты компонента (pkg:npm/lodash@4.17.19) встречаются с базой известных дефектов. Проблема не в том, чтобы «найти CVE» — сканер делает это за секунды. Проблема в том, что для типового сервиса находок будет 50–300, и почти все придут с пометкой High/Critical, но реально эксплуатируема меньшая часть. Если команда патчит всё подряд, она тратит спринты на недостижимый код; если игнорирует — пропускает то, что висит на периметре. Этот модуль ставит между сканером и решением дисциплину триажа: каждая находка получает состояние, владельца, срок и обоснование.
Ключевые идеи
VDR — это факт, VEX — это решение. VDR (Vulnerability Disclosure Report) фиксирует машинную связь «компонент ↔ CVE». VEX (Vulnerability Exploitability eXchange) отвечает на вопрос «а нас это реально касается?». Один и тот же VDR-факт «CVE-2021-44228 в log4j-core 2.14.1» превращается в разные VEX: для сервиса, где этот класс не на classpath в рантайме, — not_affected с обоснованием vulnerable_code_not_in_execute_path; для сервиса, где он на периметре, — affected, а после обновления — fixed.
VEX выдает тот, кто отвечает за продукт. NVD, БДУ, OSV и GHSA не выпускают VEX для вашего продукта: они дают внешние факты об уязвимостях. Если Организация производит ПО, VEX для конкретной версии продукта выпускает сама Организация через РБПО / Product Security / PSIRT / AppSec, владельца продукта и разработчиков. Подробный порядок: VEX в процессе РБПО.
Четыре состояния VEX (по CycloneDX/OpenVEX):
- not_affected — продукт содержит компонент, но не эксплуатируем; обязателен justification (например, vulnerable_code_not_present, inline_mitigations_already_exist);
- affected — уязвим, нужно действие (response: update, rollback, workaround_available);
- fixed — исправлено в этой версии продукта;
- under_investigation — триаж не завершён, это легитимное промежуточное состояние, а не «забыли».
Источники не равнозначны. NVD даёт CVE с CPE и CVSS, но запаздывает с обогащением. OSV.dev ориентирован на экосистемы пакетов (точные диапазоны версий по PURL). GHSA быстрее всех для GitHub-экосистемы. БДУ ФСТЭК — национальный источник: содержит уязвимости, которых может не быть в NVD, и обязателен для проектов под требования регулятора. Серьёзная программа сверяет находки по нескольким источникам — расхождение «есть в БДУ, нет в NVD» само по себе сигнал.
Как выглядит на практике
Три инструмента под разные входы:
# Grype: сканирует готовый SBOM (вход из М05)
grype sbom:./sbom.cdx.json -o cyclonedx-json > vdr.cdx.json
# OSV-Scanner: точен по lockfile (package-lock.json, go.sum, poetry.lock)
osv-scanner --lockfile=package-lock.json --format=json
# Dependency-Track: портфель SBOM, непрерывный мониторинг, API для VEX
VDR-фрагмент (CycloneDX) — это факт:
| CVE | Компонент | Версия | Источник | CVSS |
|---|---|---|---|---|
| CVE-2022-25883 | semver | 7.3.7 | OSV/GHSA | 7.5 |
VEX-запись — это решение поверх факта:
{
"vulnerability": { "id": "CVE-2022-25883" },
"affects": [{ "ref": "pkg:npm/semver@7.3.7" }],
"analysis": {
"state": "not_affected",
"justification": "code_not_reachable",
"detail": "semver вызывается только на доверенном вводе в build-time",
"response": ["will_not_fix"]
}
}
Владелец, SLA, ретест VEX-запись без трёх полей нежизнеспособна: владелец (роль, не сканер), SLA (срок по severity — например, Critical 7 дней, High 30), ретест (
under_investigationиaffectedпересматриваются при каждом обновлении базы или релизе). Состояниеnot_affectedтоже имеет срок жизни: новая версия компонента, смена сборочного варианта или новая evidence может сделать обоснование неверным.
Слепые зоны этой темы
- VEX-как-отписка: массовый
not_affectedбезjustificationиз разрешённого списка — это не триаж, а сокрытие. - Просроченный VEX: решение приняли для версии 1.2, продукт уехал на 2.0, обоснование протухло, но запись осталась
not_affected. - Только NVD: пропуск БДУ ФСТЭК как источника на проектах под регулятора.
- Доверие к severity сканера: CVSS Base ≠ риск в вашем контексте; именно для этого существует VEX.
- Findings без
fixed-замыкания: исправили, но не зафиксировалиfixed— на следующем скане та же CVE снова «горит».
Связь с нормативкой
NIST SP 800-218 SSDF требует выявлять (RV.1) и оценивать/реагировать (RV.2) на уязвимости — VDR/VEX это и реализуют. БДУ ФСТЭК — обязательный национальный источник. CycloneDX ECMA-424 нормирует VEX-расширение. OWASP SCVS описывает зрелость управления уязвимостями. Регламент закрепляем через Политика управления уязвимостями компонентов и Регламент ретеста после исправления.
Что уносим в работу
- Сканировать готовый SBOM, а не код заново — П06. Grype поверх готового SBOM.
- Для lockfile-экосистем точнее OSV-Scanner — П07. OSV-Scanner и lockfiles.
- Непрерывный мониторинг портфеля держать в Dependency-Track — П08. Dependency-Track как портфель SBOM.
- Разделять VDR (факт) и VEX (решение) в артефактах и в головах — П09. VDR и VEX различие факта и решения, П35. VEX triage.
- Сверять находки с национальным источником — П10. БДУ ФСТЭК как национальный источник.
- Использовать VEX в процессе РБПО как методический критерий: кто имеет право выпускать VEX, какие evidence обязательны и когда решение нужно пересматривать.