Створення безпечнішої екосистеми npm з Mend Renovate

Протягом останнього року відбулося кілька масштабних атак, зокрема поширення хробака Shai-Hulud, компрометація системи збірки Nx, а також витік секретів у публічні журнали GitHub Actions через вразливість у tj-actions/changed-files. Перелік подібних інцидентів можна було б продовжувати ще довго, навіть без детального розгляду кожного з них.

Ця галузь і технологічна система відчуває суттєве зростання частоти таких загроз. Лише у 2024 році зафіксовано збільшення кількості шкідливих пакетів на 156% порівняно з попереднім роком. Завдяки тому, що хмарна платформа Mend Renovate Cloud використовується у понад 1,3 мільйонах репозиторіїв, створено потужні можливості для підвищення безпеки користувачів відкритого коду, а також для впровадження більш надійних налаштувань за замовчуванням у випадках самостійного розгортання Renovate. Після серії резонансних атак на ланцюг постачання npm команда супроводу (мейнтейнерів) Mend Renovate ухвалила рішення активувати ці механізми захисту за замовчуванням для користувачів, які обирають конфігурацію “best practices”.

Для підвищення ефективності захисту від атак, кількість яких постійно зростає, команда супроводу удосконалює наявну конфігурацію “best practices”, доступну в Mend Renovate. Робота спрямована на створення ще безпечнішої конфігурації за замовчуванням, починаючи з екосистеми npm.

У найновішому релізі Mend Renovate 42 користувачі конфігурації “best practices” побачать зміни в оновленні залежностей в екосистемі npm, що тепер повинні відповідати критерію “minimum release age”. Це означає, що перед тим як Mend Renovate запропонує оновлення, має минути щонайменше триденне вікно з моменту виходу нової версії. Такий підхід забезпечує надходження у виробниче середовище лише перевірених, стабільних і надійних оновлень залежностей, що дозволяє знизити ризик атак на ланцюг постачання та водночас зберегти ефективність роботи розробників.

Як це б допомогло?

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

  • точна версія залежності не зафіксована;
  • точна версія залежності зафіксована, але виконується її надто швидке оновлення після виходу нової версії.

Відсутність фіксації версій залежностей може мати й обґрунтовані причини. Наприклад, в екосистемі npm, коли публікується пакет із кількома залежностями, який сам має багато похідних (залежних) пакетів.

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

Частину цього процесу можна спростити за допомогою автоматизації – наприклад, за допомогою таких інструментів, як Mend Renovate або Dependabot від GitHub. Втім, навіть за наявності автоматизованих інструментів все одно потрібен певний рівень ручної перевірки та рецензування оновлень.

Водночас відсутність фіксації версій залежностей може призвести до ситуацій, коли користувачі починають завантажувати нову версію пакета одразу після її виходу.

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

Навіть якщо така шкідлива залежність не потрапить безпосередньо на робочі машини розробників, вона все одно може отримати доступ до секретів або конфіденційної інформації в автоматизованих CI/CD-пайплайнах чи скористатися атаками ін’єкції промпту в системах автоматичного рецензування коду на основі штучного інтелекту.

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

Як Mend Renovate сприяє підвищенню безпеки всієї екосистеми

Як зазначено вище, у найновішому релізі Mend Renovate запроваджено перевірку “minimum release age” для всіх користувачів, які застосовують конфігурацію “best practices”. Ця перевірка активується під час оновлення будь-яких пакетів, що використовують джерело даних npm. Вона відбувається незалежно від того, який менеджер пакетів JavaScript чи TypeScript застосовується.

Запроваджене обмеження дозволяє:

  • Переконатися, що кожне оновлення залежності містить метадані про час виходу версії (release timestamp).
  • Гарантувати, що гілки оновлень не створюватимуться, доки не мине щонайменше три дні з моменту публікації релізу.

Якщо під час перевірки оновлень пакетів виявлено, що вони не відповідають зазначеним критеріям, у Dependency Dashboard від Mend Renovate з’явиться запис “awaiting status”. Такий запис вимагатиме ручного підтвердження з боку користувача та гарантує, що до роботи допускаються лише безпечні оновлення пакетів.

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

Завдяки включенню цього механізму до конфігурації “best practices”, користувачі, які обрали дотримання загальноприйнятих галузевих стандартів безпеки, отримують захист за замовчуванням. Водночас інші користувачі також можуть увімкнути цю функцію самостійно, наприклад:

{
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
  "extends": ["security:minimumReleaseAgeNpm"]
}

Крім того, поведінку цього механізму можна налаштовувати. Є можливість змінювати тривалість вікна очікування на довільну (довшу або коротшу), або ж вимикати функцію “minimum release age” для внутрішніх, перевірених пакетів, що розробляються всередині організації.

Багаторівневий захист

Окрім затримки оновлень у Mend Renovate до завершення встановленого періоду, рекомендується впроваджувати кілька рівнів захисту.

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

На момент написання статті, підтримка цієї функції вже реалізована у pnpm 10.6 та yarn 4.2.0. Також спостерігається тенденція до впровадження подібних можливостей і в інших менеджерах пакетів.

Що далі?

Після роботи над цим релізом планується подальше вдосконалення взаємодії між Mend Renovate та менеджерами пакетів, такими як pnpm і yarn, з метою глибшої інтеграції функціональності.

Також триває дослідження інших екосистем пакетів, у яких цю функцію можна буде активувати для конфігурації “best practices”. Це допоможе ще більше підвищити рівень безпеки екосистеми.

У разі пропозицій щодо роботи інструмента можна залишати повідомлення на форумі обговорень Mend Renovate.

Якщо у вас виникли запитання по Mend Renovate, або ви бажаєте отримати пробну версію продукту, будь ласка, залиште свою контактну інформацію:

Запит на пробну версію Mend.io

Підписатися на новини