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

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

П07. OSV-Scanner и lockfiles

Контекст OSV-Scanner силён там, где есть lock-файл: package-lock.json, yarn.lock, poetry.lock, go.sum, Cargo.lock. Lock фиксирует не объявленные диапазоны (^4.0.0), а разрешённые версии транзитивного дерева. OSV.dev оперирует точными диапазонами уязвимых версий по PURL — поэтому по lock-файлу находки получаются точнее, чем по package.json, где версия ещё не «застыла».

Цель

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

Проверяемый результат: два прогона OSV-Scanner (по каталогу и по конкретному lock-файлу) и JSON-отчёт, где у каждой находки есть package.version и ссылка на запись OSV/GHSA.

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

# 0. Версия инструмента (часть evidence)
osv-scanner --version

# 1. Рекурсивно по каталогу: OSV сам найдёт все манифесты и lock-файлы
osv-scanner scan source --recursive .

# 2. Прицельно по одному lock-файлу (самый точный режим)
osv-scanner scan source --lockfile=package-lock.json

# 3. Машинный отчёт для триажа
osv-scanner scan source --lockfile=package-lock.json --format=json --output osv-report.json

# 4. CI-gate: ненулевой код возврата при наличии находок
osv-scanner scan source --recursive .
echo "exit code: $?"

Старый и новый синтаксис В свежих версиях команда — osv-scanner scan source .... В версиях до 2.0 работал короткий вид osv-scanner --recursive . и osv-scanner --lockfile=... без подкоманды scan source. Если короткая форма ругается на неизвестный флаг — проверьте osv-scanner --version и используйте scan source.

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

Табличный вывод OSV-Scanner группирует находки по источнику (файлу):

╭─────────────────────────────────────┬──────┬───────────┬─────────┬──────────────────┬─────────╮
│ OSV URL                             │ ...  │ ECOSYSTEM │ PACKAGE │ VERSION          │ SOURCE  │
├─────────────────────────────────────┼──────┼───────────┼─────────┼──────────────────┼─────────┤
│ https://osv.dev/GHSA-c2qf-rxjj-qqgw │      │ npm       │ semver  │ 7.3.7            │ ...     │
│ https://osv.dev/GHSA-35jh-r3h4-6jhm │      │ npm       │ lodash  │ 4.17.19          │ ...     │
╰─────────────────────────────────────┴──────┴───────────┴─────────┴──────────────────┴─────────╯

Скелет JSON-отчёта (osv-report.json):

{
  "results": [
    {
      "source": { "path": "package-lock.json", "type": "lockfile" },
      "packages": [
        {
          "package": { "name": "semver", "version": "7.3.7", "ecosystem": "npm" },
          "vulnerabilities": [
            { "id": "GHSA-c2qf-rxjj-qqgw", "aliases": ["CVE-2022-25883"] }
          ]
        }
      ]
    }
  ]
}

Ориентир: при сканировании по lock-файлу source.type будет lockfile, и у каждого пакета будет конкретная version. Если же находок неожиданно 0, а проект явно тянет уязвимые версии — почти всегда дело в том, что lock-файла нет или он не закоммичен.

Проверка эффекта lock-файла Сравните число находок: osv-scanner scan source --lockfile=package-lock.json --format=json --output a.json против сканирования каталога без lock. Затем jq '[.results[].packages[].vulnerabilities[].id] | length' a.json. Прогон по lock-файлу обычно даёт больше и точнее адресованных находок.

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

Типичные ошибки - 0 vulnerabilities при наличии lock-файла. Lock не закоммичен или указан не тот путь. Убедитесь, что файл существует: ls -la package-lock.json. Для монорепо нужен --recursive. - unsupported lockfile / файл не распознан. OSV-Scanner определяет парсер по имени файла. Нестандартное имя (например, npm-shrinkwrap-old.json) он не подхватит — переименуйте или используйте каноническое имя lock-файла экосистемы. - Короткая форма команды не работает. Версия ≥ 2.0 требует scan source. Признак — ошибка вида unknown flag на --recursive. - CI не падает. OSV-Scanner возвращает ненулевой код при находках сам по себе; если pipeline зелёный — проверьте, что шаг не маскирует код возврата (|| true, continue-on-error).

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

Показать преподавателю: 1. osv-scanner --version; 2. два отчёта — по каталогу и по конкретному lock-файлу — и разницу в числе/точности находок; 3. osv-report.json с непустым vulnerabilities[] и видимыми version; 4. вывод о том, почему по lock-файлу результат точнее, чем по объявленным зависимостям.

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

М06. Поиск уязвимостей и управление VDR/VEX · OSV-Scanner · OSV.dev · NIST SP 800-218 SSDF (RV.1) · Политика управления уязвимостями компонентов · Требования к CI security gate

Смежные практики: П06. Grype поверх готового SBOM · П08. Dependency-Track как портфель SBOM · П09. VDR и VEX различие факта и решения