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

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

vendored source

Почему это важно для SCA/OSA

Vendoring — это когда исходники чужой библиотеки скопированы прямо в дерево проекта (src/zlib/, deps/sqlite3.c) и собираются как «свой» код, без submodule, без пакетного менеджера, без lock-файла. Для SCA это худший из миров: компонент физически присутствует и попадает в итоговый бинарь, но не оставляет ни одной декларативной зацепки — нет ни строки в conanfile, ни записи в dpkg, ни DT_NEEDED. Генератор SBOM, который ходит по манифестам и графу линковки, такой код просто не видит и молча относит к first-party. В результате уязвимость в вендоренной версии zlib не порождает ни одного finding, хотя код собран и работает.

Опасность усугубляется тем, что вендоринг почти всегда замораживает версию. Команда один раз скопировала libpng версии 1.6.34 «чтобы собиралось», и три года спустя в продукте едет именно она — со всеми накопившимися CVE, тогда как upstream давно на 1.6.43. Без явной фиксации версии в SBOM этот разрыв невидим.

Как это проявляется

Вендоренный код выглядит как обычные исходники проекта. Отличить его от first-party можно по косвенным следам — копирайтам, оригинальным VERSION/CHANGELOG, нетипичному стилю:

# Заголовок версии библиотеки внутри чужого кода — частый маркер vendoring
grep -rn "ZLIB_VERSION" src/        # → "1.2.11" — заморожённая версия
grep -rln "Copyright (C)" third_party/ | head

# Файл целиком скопирован из upstream? git его не «знает» как историю проекта
git log --oneline -- src/sqlite3.c   # одна строка "import sqlite 3.36" вместо истории

# Сверка с эталоном: хеш вендоренного файла против известного релиза upstream
sha256sum src/miniz.c

В SBOM такой компонент должен появиться как отдельная запись pkg:generic/zlib@1.2.11 с указанием, что источник — вендоренная копия, а не системный пакет. CycloneDX поле evidence.occurrences фиксирует конкретный путь в дереве, где найден компонент.

Слепая зона или приём

Главная слепая зона: вендоренный компонент по умолчанию учитывается как first-party и выпадает из анализа уязвимостей. Второй слой — потерянная версия: даже если факт наличия zlib зафиксирован, без точной версии сканеру не на что мэтчить CVE, и компонент даёт ложное ощущение «учтён, чистый». Третий — патчи: вендоренную копию часто правят руками, и она уже не равна ни одному официальному релизу, что ломает применимость как уязвимостей, так и лицензионных выводов.

Тихая реклассификация в first-party Если в отчёте сканера резко мало компонентов для проекта, который очевидно тянет крипто/сжатие/парсинг, первым делом ищите вендоринг: find . -name "*.c" -path "*third_party*" или поиск чужих копирайтов. «Маленький чистый SBOM» здесь — симптом, а не успех.

Что делать на проекте

  1. Инвентаризируйте подозрительные каталоги: third_party/, deps/, external/, vendor/, contrib/, плюс одиночные «амальгамы» (sqlite3.c, miniz.c).
  2. Для каждой вендоренной библиотеки извлеките версию из VERSION/*_VERSION макроса/CHANGELOG и зафиксируйте её в SBOM как pkg:generic/<name>@<version> (см. PURL generic fallback).
  3. Сверьте файлы с upstream-релизом по хешу; если расходятся — пометьте компонент как модифицированный (форк) и не выдавайте за чистый upstream (см. форки open source библиотек).
  4. Запишите путь occurrences в evidence.occurrences, чтобы аудит видел, откуда взят компонент (см. SBOM evidence occurrences).
  5. Заведите политику: новый вендоринг допустим только с зафиксированной версией и лицензией; ревизия — на каждом релизе.
  6. То, что не удалось привязать к версии и источнику, уносите в unresolved libraries с пониженным confidence.

Связь