Пиков / КАПО
Как читать авторский курс и нормативные материалы

Это учебные материалы, а не заключение о соответствии конкретного продукта. Организационные модели курса отделяйте от терминов стандарта: ППК в опубликованном проекте — машиночитаемый перечень, а живой реестр его версий является практикой сопровождения. Термин OSA в разных материалах имеет разный охват. Статус и обязательность нормативного документа проверяются отдельно; проект КАПО опубликован как проект первой редакции.

П35. VEX triage

Контекст практики П09. VDR и VEX различие факта и решения учит оформить одно решение. Здесь задача другая — провести триаж всего потока находок и сделать так, чтобы решения не лежали в текстовом файле, а машинно вычитались сканером: помеченные not_affected находки исчезают из выдачи, и gate перестаёт падать на разобранном шуме. Инструмент — OpenVEX vexctl (минимальный, формат-агностичный). Контролируемый результат — OpenVEX-документ, после применения которого число findings у сканера снижается ровно на разобранные CVE. Перед практикой прочитайте VEX в процессе РБПО.

Цель

По VDR из 5–10 находок: - разнести каждую находку по статусу OpenVEX: not_affected / affected / fixed / under_investigation; - для каждого not_affected указать обязательный justification из разрешённого перечня; - указать author/issuer, который вправе выпускать VEX для этой версии продукта; - собрать валидный OpenVEX-документ через vexctl create; - применить его к выводу сканера так, чтобы разобранные not_affected находки ушли из отчёта, а affected — остались.

Проверяемый результат: число findings до триажа > числа findings после применения VEX, и разница равна количеству not_affected-записей.

Команда или действие

OpenVEX через vexctl (Go-инструмент проекта OpenVEX):

# 1. Исходный поток находок (тот же SBOM, что и в gate)
grype sbom:sbom.cdx.json -o table | tee before.txt

# 2. Решение по одной находке -> запись OpenVEX
vexctl create \
  --product "pkg:npm/myapp@1.0.0" \
  --subcomponent "pkg:npm/semver@7.3.7" \
  --vuln "CVE-2022-25883" \
  --status "not_affected" \
  --justification "vulnerable_code_not_in_execute_path" \
  --status-note "semver используется только на build-time, в рантайме недостижим" \
  > vex.openvex.json

# (повторить для остальных находок; статусы affected/fixed/under_investigation
#  объединить в один документ через несколько --vuln или vexctl merge)
# Проверьте, что author/issuer в итоговом документе отражает Product Security/PSIRT/AppSec,
# а не имя сканера или внешней базы уязвимостей.

# 3. Применить VEX при сканировании: not_affected уходят из отчёта
grype sbom:sbom.cdx.json --vex vex.openvex.json -o table | tee after.txt

Разрешённые justification для not_affected (OpenVEX): component_not_present, vulnerable_code_not_present, vulnerable_code_not_in_execute_path, vulnerable_code_cannot_be_controlled_by_adversary, inline_mitigations_already_exist.

Что вы должны увидеть

Скелет OpenVEX-документа (vex.openvex.json):

{
  "@context": "https://openvex.dev/ns/v0.2.0",
  "@id": "https://openvex.dev/docs/public/vex-...",
  "author": "AppSec / Организация",
  "timestamp": "2026-06-18T10:00:00Z",
  "statements": [
    {
      "vulnerability": { "name": "CVE-2022-25883" },
      "products": [
        { "@id": "pkg:npm/myapp@1.0.0",
          "subcomponents": [ { "@id": "pkg:npm/semver@7.3.7" } ] }
      ],
      "status": "not_affected",
      "justification": "vulnerable_code_not_in_execute_path"
    }
  ]
}

Эффект применения — число findings падает:

# before.txt:  4 findings (CVE-2022-25883 High, CVE-... ...)
# after.txt:   3 findings  <- CVE-2022-25883 отфильтрована как not_affected

Признак готовности: diff между before.txt и after.txt показывает ровно те CVE, которые вы пометили not_affected; affected/under_investigation остались в отчёте; gate в CI после VEX перестал падать на разобранном шуме, но продолжает падать на нетриажированных affected.

VEX не «глушит» уязвимость — он документирует решение not_affected без justification из перечня — невалидная запись: vexctl либо отклонит её, либо она не отфильтрует находку. VEX без author/issuer и evidence — слабое управленческое утверждение. И помните: фильтрация работает, только если PURL в subcomponents точно совпадает с координатой компонента в SBOM. Несовпадение PURL = VEX «висит в воздухе», находка остаётся.

Если не получилось

Критерий зачёта

Показать преподавателю: (1) VDR из 5–10 находок и таблицу триажа со статусом, issuer/владельцем и evidence по каждой; (2) валидный OpenVEX-документ с author и justification из перечня для всех not_affected; (3) before.txt/after.txt, где разница findings = числу not_affected; (4) пояснение, чем эта практика отличается от П09. VDR и VEX различие факта и решения (там — одно решение, здесь — машинно применяемый триаж потока и срок пересмотра not_affected).

Нормативная связка