SCA-аналіз в CI: OWASP Dependency-Check з кешем і придушенням

Збірка падає через одну вразливу залежність — а команда дізнається про це в останній момент. Ми налаштовуємо SCA-аналіз в контурі збірки під ключ: з кешем, придушенням хибних спрацювань і зрозумілим регламентом для розробників. Перевірка перестає гальмувати конвеєр і починає працювати на вас.
Часті запитання

OWASP Dependency-Check у збірці: де вузьке місце

OWASP Dependency-Check ставлять у збірку як обов’язковий крок: доки перевірка бібліотек не пройшла, артефакт не публікується.

На проєкті із сотнями прямих і транзитивних залежностей цей крок швидко стає вузьким місцем збірки — він один займає більше часу, ніж компіляція, тести й пакування разом узяті.

Перша причина — робота з базою уразливостей. На чистому агенті кожен запуск заново викачує й перебудовує локальний індекс: десятки тисяч записів, тривалі мережеві операції, плаваючі таймаути.

Збірка падає не через код, а через недоступність зовнішнього джерела, і перезапуск не гарантує, що наступний прогін пройде.

Друга — потік хибних спрацювань. Зіставлення за координатами та евристиками регулярно позначає безпечну бібліотеку уразливою: не визначився ідентифікатор пакета, не розпізналася версія, збіглося ім’я.

Такий шум блокує випуск, і команда йде одним із двох шляхів: вимикає крок повністю або послаблює поріг до стану, коли реальні уразливі залежності проходять непоміченими.

Третя — невідтворюваність. Результат залежить від моменту оновлення бази й від того, які модулі встигли завантажитися. Той самий коміт сьогодні зелений, завтра червоний, а порівняти два звіти між запусками нічим: набори знахідок непорівнянні.

Далі розбираємо, як це закривається: кеш бази між збірками, обмеження області аналізу, файл придушення з обґрунтуванням на кожен запис і фіксація звіту як артефакту збірки.

Що змінюється після впровадження SCA-контролю

До впровадження аналіз залежностей запускався на кожній зміні повністю, і час збірки зростав лінійно разом із кількістю модулів. Чим більше сервісів у репозиторії, тим довше чекати на вердикт — і тим частіше перевірку оминали.

OWASP Dependency-Check разом із кешем результатів аналізу змінює цю арифметику: перераховуються лише змінені гілки дерева залежностей, решта піднімається з кешу. Час збірки перестає зростати разом із кількістю модулів і визначається реальним обсягом правок.

Ключ кешу прив’язаний до файлу блокування залежностей і версії бази уразливостей, тому повторний аналіз на тій самій ревізії дає ідентичний звіт.

Це і є відтворюваність перевірки: результат у середовищі збірки та на машині інженера збігається, спірну знахідку можна розібрати локально, не чекаючи черги.

Далі працює політика придушення спрацювань. Кожне виключення — окремий запис з обґрунтуванням і терміном перегляду: уразлива функція не викликається, транзитивна залежність надходить лише в тестову область.

Частка хибних спрацювань падає в рази — у звіті залишаються десятки реальних знахідок замість сотень шумових.

Збірка зупиняється при перевищенні заданого порогу серйозності, тому клас відмов «уразлива бібліотека поїхала в реліз» закривається на вході. Перевірка перестає бути гальмом і працює фільтром: далі проходять лише розібрані залежності.

Режими запуску перевірки залежностей: порівняння

Режими запуску аналізу відрізняються не суворістю, а тим, що кожен із них кешує між прогонами і на якому кроці зупиняє збірку.

Суцільний прогін дає повну картину, але на великому репозиторії додає до кожної збірки десятки хвилин; інкрементальна перевірка за зміненими модулями вкладається в хвилини, але бачить лише зачеплені гілки залежностей.

Режим Коли підходить Обмеження
Суцільний аналіз на кожному коміті Кілька модулів, важлива реакція на будь-яку нову залежність Час збірки зростає з розміром репозиторію, перевірку починають оминати через примусовий пропуск
Інкрементальний за зміненими модулями Монорепозиторій із частими комітами Потрібен коректний граф модулів: транзитивна залежність може змінитися в незміненому модулі й залишитися непоміченою
Перевірка за розкладом Великі репозиторії з рідкими релізами Між прогонами уразлива версія встигає потрапити в основну гілку, а результат надходить не тому, хто вніс зміну
Тільки перед збіркою релізу Зовнішні постачання та контури з формальним прийманням Пізній зворотний зв’язок: правки щодо залежностей спливають на заморожуванні, борг з уразливостей накопичується між релізами

Як режими поєднуються

Інкрементальний аналіз на комітах відсікає очевидне, спільне сховище кешу між прогонами й агентами прибирає повторне завантаження бази уразливостей і тримає час відгуку стабільним, а повний прогін перед релізом працює шлагбаумом.

Обмеження аналізу — хибні спрацювання та залежності без публічних ідентифікаторів уразливостей — знімаються suppression-файлом, але в кожного придушення має бути термін перегляду, інакше виключення живуть роками й закривають реальні знахідки.

Порядок впровадження: від аудиту до передачі

Впровадження розбито на сім кроків, і кожен закінчується перевіреним артефактом — конфігурацією, схемою або регламентом, а не звітом про роботу. Порядок вибудувано так, що перші етапи не чіпають робочі гілки: спочатку знімаємо картину, потім змінюємо конвеєр.

Так аналіз залежностей не блокує реліз у найневдаліший момент, а команда встигає звикнути до нових перевірок.

  1. Аудит конвеєра збірки: фіксуємо, де саме збираються артефакти, які кроки кешуються, скільки часу займає чиста збірка і де в ній з’являються зовнішні бібліотеки.
  2. Інвентаризація залежностей: збираємо перелік прямих і транзитивних компонентів, позначаємо застарілі та занедбані, відзначаємо модулі з найширшим деревом залежностей.
  3. Схема кешу: OWASP Dependency-Check тягне базу уразливостей при кожному запуску — виносимо її в окремий том, прив’язаний до версії бази, щоб повторні збірки не завантажували її заново й не втрачали результати при падінні мережі.
  4. Налаштування запуску: обираємо режим сканування, набір форматів звіту, момент виклику щодо тестів і поріг, при якому збірка зупиняється.
  5. Правила придушення: описуємо спрацювання, які не стосуються нашого коду, з обов’язковим коментарем і терміном перегляду — інакше шум швидко знецінює звіт.
  6. Перевірка на реальних збірках: проганяємо конфігурацію на кількох модулях, вимірюємо приріст часу збірки та частку спрацювань, які дійсно потребують правок.
  7. Передача регламентів: віддаємо документ про порядок оновлення бази, розбір нових спрацювань і перегляд придушень, проводимо розбір із командою і залишаємося на зв’язку на період перших змін.

Комплект постачання: конфігурації, політики, регламенти

Комплект постачання зібрано так, щоб аналіз залежностей жив у вашому репозиторії без нашої участі.

Після впровадження OWASP Dependency-Check залишаються конфігурації, політики та інструкції — їх достатньо, щоб новий інженер підняв перевірку й зрозумів, чому звіт виглядає саме так.

  • Конфігурація аналізу — єдиний профіль: список сканованих модулів, глибина розбору транзитивних залежностей, формати звітів і умова виходу кроку збірки з ненульовим кодом.
  • Схема кешу — до якого набору файлів прив’язаний ключ, коли він скидається і як зберігається база уразливостей, щоб повторні прогони не тягли її заново.
  • Списки придушення — файл у форматі XML, де в кожного запису є обґрунтування, власник і термін перегляду; запис без коментаря не проходить рев’ю.
  • Пороги спрацювання — окремі правила для релізної гілки та для повсякденних: що зупиняє збірку, а що йде попередженням у звіт.
  • Інструкції для розробників — як прогнати перевірку локально до коміту, як читати звіт щодо транзитивних залежностей і коли заводиться придушення.
  • Регламент оновлення бази уразливостей — розклад і контроль фактичного оновлення: без цього звіт будується за застарілими даними й виглядає благополучно на порожньому місці.

Усе це лежить у репозиторії та проходить рев’ю як код: зміни порогів видно в історії, а на записи придушення можна посилатися під час розбору інциденту.

Кейс: як змінилися час збірки та кількість спрацювань

На одному конвеєрі перевірку залежностей запускали повністю на кожен коміт: інструмент завантажував свіжу базу уразливостей, проганяв усі модулі й повертав звіт на кілька сотень рядків.

Збірка займала 16 хвилин, а крок стояв в обов’язкових — правка невеликого сервісу чекала на повний прогін.

Що змінили

Базу OWASP Dependency-Check почали кешувати між запусками й оновлювати за розкладом, а не на кожному коміті; ключем стала контрольна сума файлу залежностей — при її зміні база перечитується, при незмінній береться зі сховища.

Завели список придушень: у кожного виключення є ідентифікатор уразливості, модуль, обґрунтування та дата перегляду, тому це рішення з власником, а не рядок, щоб збірка пройшла.

Що стало

Типова збірка скоротилася з 16 до 4 хвилин, повний прогін з оновленням бази залишився в нічному розкладі. Частка шумових спрацювань упала з 78% до 15% — переважно за рахунок виключень для залежностей тестового контуру та уразливостей без застосовного вектора атаки.

Реальні знахідки стали видні: за квартал до команди дійшли три критичні уразливості в бібліотеках, одна — у компоненті, який підтягувався транзитивно й не потрапляв у ручний перегляд. Довіра до перевірки тримається на тому, що звіт короткий, а кожне спрацювання хтось уже розібрав.

Чим Dependency-Check відрізняється від перевірки ліцензій?

Dependency-Check відповідає на одне питання: які відомі уразливості є в сторонніх бібліотеках проєкту.

Він читає маніфести та lock-файли, звіряє версії з базами уразливостей і видає звіт із критичністю та шляхом до проблемної транзитивної залежності — але код самого проєкту не розбирає.

Перевірка ліцензій вирішує інше завдання: чи можна постачати продукт із цією бібліотекою. Важливі тип ліцензії, копілефт-умови та вимоги атрибуції — результат тут правовий ризик, а не уразливість. Сканер покаже ліцензію у звіті, але вердикт залишається за юристом.

Перевірка Що знаходить Чого не бачить
Dependency-Check відомі уразливості в бібліотеках, включно з транзитивними власний код, секрети
Перевірка ліцензій тип ліцензії, копілефт, вимоги атрибуції експлуатабельність, юридичний вердикт
Пошук секретів ключі та токени у файлах і історії комітів уразливості в залежностях
Статичний аналіз коду небезпечні потоки даних у нашому коді версії підключених бібліотек

Пошук секретів і статичний аналіз працюють за нашою кодовою базою: один шукає ключі та токени у файлах і історії комітів, другий — небезпечні потоки даних. Уразливість усередині транзитивної залежності не побачить ні той, ні інший.

Межі відповідальності проходять за джерелом даних: сканування залежностей читає маніфести, статичний аналіз і пошук секретів — наш код.

Перетини виникають у конвеєрі, тому придушення хибних спрацювань тримаємо централізовано — інакше одна бібліотека спливає в трьох звітах під різними формулюваннями.

Технічні сумніви: кеш, шум, оновлення бази

Інженерні сумніви навколо SCA-контуру зазвичай одні й ті самі: наскільки свіжа база в кеші, що робити в закритому контурі й чи не перетвориться придушення спрацювань на звалище. Нижче — короткі відповіді за кожним пунктом, із тим, що потрапляє у звіт і конфігурацію збірки.

База уразливостей у кеші застаріває між прогонами?

Кеш прив’язаний до контрольної суми файлу бази: завантаження йде лише при її зміні, розклад оновлення — раз на добу. У звіті фіксуються версія бази та час її формування, тому за кожним прогоном видно, на яких даних отримано результат.

Якщо оновлення не пройшло, збірка не «зеленіє» мовчки — вона позначається як перевірка на застарілій базі.

Збірка йде без виходу в зовнішню мережу — оновлення можливе?

Так. Піднімаємо внутрішнє дзеркало: файл тягне один вузол за дозволеним маршрутом, решта складальників забирають його з внутрішнього сховища. Сам розбір залежностей працює офлайн за локальним кешем, зовнішні звернення йому не потрібні.

Адреса дзеркала та параметри проксі описуються в конфігурації, щоб переїзд на новий контур не ламав перевірку.

Бібліотеку не можна оновити — шум залишиться назавжди?

На такі випадки працює придушення спрацювань (suppression): правило прив’язується до ідентифікатора уразливості й конкретного артефакту, а не вимикає перевірку повністю. У кожного запису є причина, власник і дата перегляду — застаріле придушення спливає окремим блоком у звіті.

Супровід правил зводимо до ревізії раз на квартал: у звіті видно частку хибних спрацювань і кількість активних придушень, за ними й вирішуємо, що чистити.

Обговоримо задачу: що надіслати для оцінки

Щоб оцінка спиралася на факти, а не на загальні слова, потрібен зріз поточного конвеєра збірки: чим збираються модулі, на яких стадіях уже запускаються перевірки, скільки живе один прогін і де він упирається в ліміт.

Окремо важливий характер проєкту — монорепозиторій із сотнями транзитивних залежностей і невеликий сервіс із десятком прямих бібліотек потребують різного режиму запуску OWASP Dependency-Check і різної глибини кешування бази уразливостей.

  • Схема конвеєра: стадії, порядок кроків, де зараз виконується аналіз залежностей і що відбувається при падінні збірки.
  • Файли залежностей за кожним модулем: маніфести та файли блокування, прямі й транзитивні бібліотеки, частка внутрішніх пакетів із приватного репозиторію.
  • Приклади шумних спрацювань: уразливості без доступного виправлення, хибні збіги за іменем пакета, записи, які вже прийнято ігнорувати — за ними збираємо suppression-файл з обґрунтуванням.
  • Бюджет часу: скільки секунд або хвилин допустимо додати до збірки, чи потрібен запуск лише на змінених модулях і чи допустимий звіт у режимі «не блокує».
  • Мережеві обмеження: чи є доступ до зовнішніх джерел баз уразливостей, чи потрібен внутрішній дзеркальний репозиторій та офлайн-оновлення даних.
  • Куди складати результати: формат звіту, місце зберігання, чи потрібне вивантаження в систему контролю якості та повідомлення в канал команди.
  • Політика щодо критичності: які рівні зупиняють збірку, хто затверджує виключення і з якою періодичністю переглядаємо список придушень.

Із цим набором ми повертаємося з оцінкою та планом впровадження: перелік етапів, порядок викочування на один сервіс, потім на інші, і точки, де можна відкотитися без зупинки розробки.

Наші компетенції:

Останні роботи

  • Розробка сайту компанії B2B ADVANCE
    Розробка сайту компанії B2B ADVANCE
    1542
  • Розробка веб-додатків для компанії FEEDME
    Розробка веб-додатків для компанії FEEDME
    1393
  • Розробка веб-сайту для компанії БЕЛФІНГРУП
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1081
  • Розробка інтернет магазину для компанії FURNORO
    Розробка інтернет магазину для компанії FURNORO
    1368
  • Розробка логотипу компанії B2B Advance
    Розробка логотипу компанії B2B Advance
    815
  • Розробка веб-додатків для компанії Enviok
    Розробка веб-додатків для компанії Enviok
    1139