Застосунок - це ваш код плюс сотні пакетів Composer і npm, кожен з яких може мати власні залежності. Атака на ланцюжок постачання - компрометація не вашого коду, а чогось, від чого він залежить: пакета, інструмента збирання, CI.
Як це відбувається:
- Викрадений обліковий запис мейнтейнера - і в популярний пакет потрапляє шкідлива версія.
- Typosquatting - пакет з назвою, схожою на популярну.
- Dependency confusion - публічний пакет з назвою вашого внутрішнього, який менеджер пакетів вибирає замість приватного.
- Шкідливі скрипти встановлення -
postinstallу npm виконується одразу під часnpm install. - Компрометація CI - секрети з пайплайна, підміна артефактів збирання.
Захист:
- Lock-файли в репозиторії (
composer.lock,package-lock.json) і встановлення лише з них у CI й на проді (composer install,npm ci). - Аудит вразливостей:
composer audit,npm audit, Dependabot чи Renovate з автоматичними pull request на оновлення. - Оновлення - регулярно, але не наосліп: читати changelog, дати новій версії кілька днів «відлежатися», переглядати diff у критичних пакетах.
- Менше залежностей: кожен пакет - ще одна точка довіри. Для дрібної функції часто простіше написати кілька рядків, ніж додати пакет.
- Обмеження скриптів:
npm ci --ignore-scripts, де можливо; у Composer плагіни потребують явного дозволу (allow-plugins). - Захист CI: мінімальні права токенів, секрети лише для гілок, яким довіряєте, закріплення сторонніх GitHub Actions за хешем коміту, а не тегом.
- Перевірка походження: підписи й attestations пакетів (npm provenance, Sigstore), SBOM для розуміння, що саме в застосунку.
Висновок: залежність - це чужий код, який ви запускаєте з повними правами застосунку. Ставитися до неї варто відповідно.
Докладніше в документації: OWASP: керування вразливими залежностями