Дизайн аудиту ланцюга постачання
Принципи перевірки, що лежать в основі зафіксованого тесту аудиту ланцюга постачання
Аудит ланцюга постачання підтверджує ефективність заходів контролю залежностей репозиторію виключно на основі файлів, що були зафіксовані у репозиторії. Аудит, який можна обдурити (або який проходить, навіть якщо нічого не перевіряє), гірший за його відсутність, оскільки зелений результат у такому разі свідчить про неперевірений стан. Наведені нижче принципи не дозволяють пройти аудит у разі порушення контролю та роблять його проведення доцільним.
Щодо того, які заходи контролю існують і чому, див. розділ «Безпека ланцюга постачання»; що робити, коли аудит не проходить у вашому PR, див. секцію аудиту документів залежностей.
Принципи
- Перевірка виключно на основі файлів, що потрапили у репозиторій. Аудит зчитує блокування, маніфести,
.npmrcтаnetlify.toml(ніколи — мережу чи дерево встановлених файлів), тому він працює швидко, в автономному режимі і не піддається впливу стану, який повинен перевіряти. - Включати цілі структури до списку дозволених; не використовуйте шаблони у списку заборонених. Регулярний вираз у списку заборонених для формату конфігурації пропускає правильні варіанти, яких він не перераховує (ключі TOML у лапках, з крапками та у вбудованих таблицях обходять список заборонених для ключів env). Фіксація всієї перевіреної структури (точні набори ключів, точні значення) є надійнішою і зазвичай коротшою.
- Виконання синтаксичного аналізу; не сканування рядків. Синтаксичний аналізатор формату визначає його семантику. Регулярний вираз на рівні рядка неправильно моделює її, не повідомляючи про це: таблиця контексту, яку він не розпізнає, все одно має значення для Netlify.
- Точні ідентифікатори; відсутність збігу за префіксом або прапорцем. Збіг за префіксом допускає додавання доповнення
&& npm install ...до скрипту, якому аудит довіряє за назвою. - Закрита помилка у разі відсутності. Кожна перевірка підрахунку містить перевірку мінімального значення, тому порожній вхідний параметр не може стандартно пройти перевірку; записи, у яких відсутнє очікуване поле, викликають помилку, а не пропускаються.
- Привʼязка до ідентичності, якій довіряє npm. npm визначає ідентичність пакунка за його URL-адресою в реєстрі
resolved, а не за ключем блокування чи полемversion, тому аудит повʼязує всі три елементи разом; перевірка лише тих полів, яким npm не довіряє, дозволяє пройти перевірку навіть у разі невідповідності, на яку npm би зреагував. - Один «дім» на кожну інваріанту. Список, що перевіряється у двох файлах, може змінюватися; аудит імпортує спільні значення з модуля-власника, а модульний тест цього модуля фіксує вміст.
- «Спочатку червоне». Новій перевірці довіряють лише після того, як навмисно пошкоджений вхідний параметр призвів до її провалу. Хибний «зелений» стан гірше за «червоний».
- Асерції визначають очікуваний стан, а у разі рутинних спрацьовувань — і виправлення: асерція
allowScriptsвказує версію, до якої має бути переміщений запис у результаті підвищення версії залежності, тому повідомлення про помилку є і виправленням. - Вкажіть межі сфери дії. Поверхні, які аудит навмисно не охоплює, вказуються в аудиті та документації залежностей, щоб відсутність охоплення ніколи не сприймалася за перевірене охоплення.
- Кожна перевірка мусить виправдовувати своє існування. Безпека забезпечується завдяки конструкції засобів контролю та процесу перевірки, а не накопиченням тверджень: кожне з них обтяжує учасників та розробників при кожному втручанні. Перевірка має місце лише тоді, коли вона виявляє те, чого рецензія явно не може виявити: непрозору поверхню з високим рівнем авторитету, таку як блокування, або семантику, занадто незрозумілу, щоб її можна було помітити на око. Якщо засіб контролю вже не працює під час виконання, аудит не підтверджує його знову; коли витрати на підтримку перевірки перевищують її цінність для виявлення, її скорочення є правильним кроком, а не послабленням.
Принципи в аудиті
Один приклад на кожен принцип; тестовий файл є авторитетним переліком тверджень.
| Принцип | Екземпляр в аудиті |
|---|---|
| Committed files alone | Кожен вхід читається з checkout; набір тестів запускається без мережі |
| Allowlist whole shapes | netlify.toml: таблиці верхнього рівня, ключі build та набори env-ключів deepEqualed |
| Parse, don’t line-scan | netlify.toml розбирається за допомогою smol-toml до будь-яких тверджень |
| Exact pins | Скрипти install-closure порівнюються через assert.equal, ніколи match |
| Fail closed on absence | registryPackages > 0 |
| Identity npm trusts | resolved URL кожного запису реєстру має називати власний пакунок та версію |
| One home per invariant | UNSAFE_HUGO_ENV імпортується з rebuild-hugo-extended.mjs |
| Red-first | PR кожного hardening-коміту зазначає зламаний вхід, що змусив його спочатку не пройти перевірку |
| Assertions name the fix | allowScripts covers hugo-extended at its locked version X |
| Stated scope boundary | Коментар заголовка аудиту називає виключені поверхні |
| Checks earn their keep | Форма межі рушіїв підтверджується, а не її значення; engine-strict забезпечує їх під час встановлення |