Как читать авторский курс и нормативные материалы
Это учебные материалы, а не заключение о соответствии конкретного продукта. Организационные модели курса отделяйте от терминов стандарта: ППК в опубликованном проекте — машиночитаемый перечень, а живой реестр его версий является практикой сопровождения. Термин OSA в разных материалах имеет разный охват. Статус и обязательность нормативного документа проверяются отдельно; проект КАПО опубликован как проект первой редакции.
статическая линковка
Почему это важно для SCA/OSA
Статическая линковка — каноничная слепая зона C/C++ SCA. При связывании с архивом .a линкер копирует нужные объектные файлы библиотеки прямо внутрь итогового бинаря. После этого отдельной сущности «библиотека» не остаётся: нет файла .so, нет записи в динамической секции, нет пакета на хосте. Компонент физически присутствует в продукте, но из всех привычных следов исчезает — и автоматический скан готового бинаря его не покажет.
Для управления уязвимостями это худший случай: вшитая статически уязвимая библиотека даёт false negative при матчинге. Сканер честно сообщает «динамических зависимостей нет», а в бинаре при этом сидит, например, старая OpenSSL с известной CVE. Поэтому статическая линковка — главный аргумент в пользу того, что полнота состава достигается на этапе сборки, а не поздним сканом.
Как это проявляется
Один и тот же код, собранный динамически и статически, даёт разную видимость зависимости. В динамическом бинаре библиотека есть в DT_NEEDED; в статическом — её там нет вообще:
$ readelf -d ./app_dyn | grep NEEDED
0x0...0001 (NEEDED) Shared library: [libssl.so.3]
0x0...0001 (NEEDED) Shared library: [libcrypto.so.3]
$ readelf -d ./app_static | grep NEEDED
0x0...0001 (NEEDED) Shared library: [libc.so.6]
OpenSSL «испарилась» из секции .dynamic — но код её внутри. Доказать присутствие можно лишь косвенно: по символам (nm -C найдёт SSL_*, если бинарь не stripped) или по строке версии в данных:
$ strings ./app_static | grep -iE 'OpenSSL [0-9]'
OpenSSL 3.0.11 19 Sep 2023
И это в лучшем случае. Строки версии вшивают не все библиотеки, а strip убирает символы (см. stripped binaries) — тогда не остаётся даже косвенного следа.
Поздний скан ≠ build-scan У статически слинкованного компонента нет ни soname, ни пакета, ни (в stripped-бинаре) символов. Версию приходится угадывать по уцелевшей строке — если она есть. Единственный надёжный источник состава здесь — журнал сборки и флаги линковки (
-l:libssl.a,-Wl,-Bstatic,-static), которые видны только во время сборки.
Слепая зона или приём
Сама статическая линковка и есть слепая зона; приём — ловить её там, где она ещё видна по имени. В строке линковки -l:libcrypto.a или -Wl,-Bstatic -lfoo библиотека названа явно — это единственное место, где статический компонент фигурирует под своим именем и версией пакета. Поэтому build-inventory по логу сборки (разбор compile_commands.json и строк линкера, см. компиляция и линковка) — не дополнение, а обязательное условие: без него статика выпадает из SBOM молча.
Если бинарь уже собран, а лога нет, остаётся честный результат «компонент присутствует, версия из бинаря недоступна» — и пометка в реестре неопознанных, а не пустая строка в SBOM.
Что делать на проекте
- Считать каждый статически слинкованный компонент кандидатом в false negative и не полагаться на скан готового бинаря.
- Источник истины для статики — журнал сборки: искать в нём
-l:lib*.a,-Wl,-Bstatic,-static,-static-libstdc++(см. компиляция и линковка). - Если лога нет — пробовать косвенные следы:
nm -C(символы) иstrings | grep -iE 'версия'; результат фиксировать с пониженным confidence. - На stripped-бинаре, где
nmпуст и строки версии нет, оформлять компонент как «присутствует, версия недоступна» — это корректный исход, а не провал. - Любую вшитую библиотеку без подтверждённой версии заносить в реестр неопознанных по порядку работы с неопознанной библиотекой.
- Требовать от поставщиков SBOM, собранный на этапе сборки, а не реконструированный из бинаря, — для статики это критично.
Связь
- Модуль: М09. C/C++ legacy
- Практики: П23. Статическая линковка как слепая зона · П19. C C++ make build inventory
- Нормативка: NIST SP 800-218 SSDF (PS.3.2, PW.4) · BSI TR-03183-2 v2.1.0 · ГОСТ Р 56939-2024
- Шаблон: Порядок работы с неопознанной библиотекой
- Смежные заметки 06: динамическая линковка · компиляция и линковка · ELF и разделы dynamic · stripped binaries · debug symbols как evidence