Сповіщення про залежності ставлять вузьке й перевірюване запитання: чи з'являються версії залежностей, до яких насправді резолвиться цей репозиторій, у якихось опублікованих сповіщеннях про безпеку?
Метрика має 20% категорії Безпека, поряд зі станом безпеки із 80%.
Вага навмисно скромна. Калібрування на шістнадцяти широко вживаних пакетах показало п'ятнадцять узагалі без відомих сповіщень: добре доглянуті проєкти справді не постачають вразливих залежностей, тож чистий результат тут — норма, а не відзнака. Сигнал, який майже завжди дає повний бал, не повинен важити більше за той, що справді змінюється.
Що вимірюється: те, що встановлює споживач
Для репозиторію, який публікує пакет, оцінюваним набором є runtime-замикання залежностей цього пакета — кожен пакет, що його реально тягне інсталяція, прямий і транзитивний, — резолвлене з відкритого індексу deps.dev. Звіт називає точний пакет і версію, які оцінено.
Лише коли репозиторій не публікує нічого, обстеження звертається до власного графа залежностей репозиторію. Це інша річ: він містить ще й піниї розробки та тестування, яких жоден інсталятор не завантажує. Звіти в цій області це зазначають.
Різниця не академічна. Граф Flask містить старі версії Werkzeug і Jinja, які проєкт свідомо закріплює для тестування; вони несуть сповіщення, і жодна з них не доходить до того, хто встановлює Flask. Опубліковане замикання — шість пакетів, жоден не уражений.
Замикання наразі резолвляться для пакетів npm, PyPI, crates.io та Maven. Репозиторії, що публікують у Go, NuGet, RubyGems, Packagist чи Hex, оцінюються за своїм графом, доки індекс їх не охопить: це обмеження джерела даних, а не судження про ці екосистеми.
Звідки беруться дані
Кожне обстеження читає резолвлений набір залежностей репозиторію — прямі залежності плюс транзитивне замикання під ними — з графа залежностей, який хостингова платформа вже обчислює з закомічених маніфестів і lock-файлів.
Цей набір звіряється з OSV — відкритою базою сповіщень під егідою Open Source Security Foundation, яка зводить GitHub Security Advisories, PYSEC, RUSTSEC, базу вразливостей Go та інші під однією схемою. OSV безкоштовна, публічна й версіонована — ті самі властивості, які роблять Scorecard захищеною основою для стану безпеки.
Той самий запит повертає також пакети, про які повідомлено як про шкідливі. Це не вразливості, і тут вони не рахуються: вони не несуть ані рівня критичності, ані виправленої версії, а подаються й оцінюються окремо як шкідливі залежності. Пакет, який з'являється там, не з'являється додатково в підрахунках на цій сторінці.
Що повідомляється
Для кожного ураженого пакета: резолвлена версія, чи це пряма, чи непряма залежність, найгірший рівень критичності серед його сповіщень, скільки сповіщень застосовно, їхні ідентифікатори і — там, де сповіщення це вказує, — версія, у якій проблему виправлено.
Рівень критичності береться з власної позначки бази сповіщень. Записи без такої позначки, що часто трапляється в PYSEC, подаються як невідомий, а не отримують вгадане значення.
Як це оцінюється
Три компоненти:
| Компонент | Вага |
|---|---|
| Прямі залежності без відомих сповіщень | 35 |
| Непрямі залежності без відомих сповіщень | 25 |
| Немає задавнених сповіщень | 40 |
Прямі важать більше за транзитивні, бо це власний задекларований вибір проєкту; транзитивні приходять разом із ними.
Критичність — це опублікований базовий бал CVSS, а не грубий ярлик. Кожен уражений пакет додає свій бал за шкалою 0–1. Власні позначки бази (critical/high/moderate/low) використовуються лише там, де сповіщення не публікує CVSS-вектора.
У перших двох компонентах домінує найгірша окрема знахідка, а решта обсягу важить дедалі менше. Одна залежність критичного рівня коштує близько трьох чвертей свого компонента; вісім низького — близько третини. Цей порядок навмисний: сто дрібних сповіщень не дорівнюють одному критичному. При цьому обсяговий доданок ніколи не опускає компонент до нуля, тож проєкт із 300 знахідками все одно стоїть нижче за проєкт із 30, а не зрівнюється з ним.
Третій компонент питає інше: скільки часу виправлення вже доступне? Потрапити під сповіщення, опубліковане минулого тижня, — невдача. Досі резолвитись у версію, уражену сповіщенням річної давності, — це нездатність стежити за залежностями. Пакет потрапляє сюди, коли його найстаріше сповіщення переходить межу 90 днів. Якщо в жодного сповіщення немає дати публікації, компонент виключається з перенормуванням ваги, а не вважається чистим.
Набір залежностей без відомих сповіщень отримує повний бал за всіма трьома.
Покриття декларується, а не припускається
Деякі записи в графі залежностей не мають зафіксованої версії. Пакет без версії неможливо звірити з діапазоном версій, тому його пропускають і рахують — кожен звіт зазначає, скільки залежностей оцінено, а скільки ні.
Репозиторії, у яких граф залежностей недоступний або вимкнений, не караються. Метрика виключається, а залишкова вага категорії «Безпека» перенормовується — так само, як із будь-яким іншим недоступним входом; див. індекс здоров'я.
Чого ця метрика не стверджує
Сповіщення тут означає рівно одне: версія, записана в графі залежностей, потрапляє в уражений діапазон сповіщення.
Це не означає, що вразливий шлях виконання досяжний із цього проєкту, і не означає, що проєкт експлуатований. Більшість сповіщень у великому транзитивному замиканні в конкретному контексті не експлуатовані.
Це також не відрізняє те, що проєкт постачає, від того, чим він себе збирає й тестує. Граф залежностей містить пінии розробки й тестування, і репозиторій, який свідомо тестується проти старої версії бібліотеки, покаже тут цю версію. Поділ на прямі та непрямі — найближчий доступний проксі, він подається для кожної знахідки, але він залишається проксі.
Читайте разом із сигналами, а не гарантіями: чистий результат не є гарантією безпеки, а знахідка — це привід подивитися, а не вирок.
Чому це окремо від стану безпеки
Власна перевірка вразливостей у Scorecard звертається до тієї самої бази сповіщень і вже дає внесок у стан безпеки. Оцінювати другий похідний від OSV сигнал усередині тієї самої метрики означало б порахувати ті самі свідчення двічі.
Розділення також утримує обидві метрики чесними щодо їхньої різної зернистості. Стан безпеки питає, чи несе проєкт відомі вразливі залежності взагалі, — як одна перевірка з дев'ятнадцяти. Ця метрика питає, які саме пакети, з якою критичністю і у якій версії виправлено — тобто у формі, якої відповідь має набути, перш ніж за нею можна діяти.