В июле 2026 года GitHub включил по умолчанию новое поведение для Dependabot version updates: перед тем как открыть PR на обновление npm-зависимости, Dependabot теперь ждёт минимум 3 дня с момента публикации новой версии пакета. Это называется dependency cooldown, и это прямой ответ на схему атак, которая раз за разом срабатывала весь 2026 год — от компрометации Mastra AI в июне до атаки на репозитории AsyncAPI в июле.
Почему именно скорость обновления — это уязвимость
Логика атак, которые мы разбирали в других гайдах (Shai-Hulud, Mini Shai-Hulud, Mastra AI), одинаковая: злоумышленник получает доступ к аккаунту мейнтейнера или к CI/CD пайплайну публикации, выпускает вредоносную версию, и она начинает расходиться по проектам за минуты — просто потому, что автообновления подхватывают новый релиз мгновенно, ещё до того, как кто-либо успел заметить неладное.
Атака на Mastra AI в июне 2026 наглядно это показала: свыше 140 пакетов в scope @mastra были переопубликованы за 19 минут. Любой проект с автообновлением без задержки, который сделал npm install в этом окне, получал вредоносный код.
Как это устроено в Dependabot
Настройка cooldown задаётся в .github/dependabot.yml через поле cooldown:
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "daily"
cooldown:
default-days: 3
semver-major-days: 7
semver-minor-days: 3
semver-patch-days: 1
Обратите внимание на дифференциацию по типу версии: major-обновления получают более долгое окно (7 дней) по умолчанию логичнее — они и так требуют больше ручного тестирования, а patch-версии (обычно баг-фиксы) — более короткое (1 день). Security-обновления не задерживаются — если Dependabot видит, что новая версия исправляет известную уязвимость, PR открывается немедленно, cooldown к таким обновлениям не применяется.
Что делать, если вы не используете Dependabot
Renovate поддерживает похожую механику через поле minimumReleaseAge в renovate.json:
{
"packageRules": [
{
"matchUpdateTypes": ["major"],
"minimumReleaseAge": "7 days"
},
{
"matchUpdateTypes": ["minor", "patch"],
"minimumReleaseAge": "3 days"
}
]
}
Если у вас ручной или собственный скрипт обновления зависимостей — сама идея переносится без труда: перед npm update или npm install <pkg>@latest проверяйте дату публикации версии через npm view <пакет> time --json, которая вернёт объект с датами всех релизов, и сравнивайте с текущей датой. Ровно эту проверку и делает наш npm Dependency Cooldown Calculator — вставляете список пакетов с датами релизов, получаете статус по каждому.
Cooldown — не панацея, а один слой защиты
Три вещи, которые cooldown не решает:
Таргетированную атаку на конкретный проект — если атакующий целится именно в вас, а не рассылает вредоносный релиз массово, скорость обновления вообще не при чём.
Install-скрипты у пакета, который уже прошёл cooldown — это отдельный вектор, который закрывает allowScripts (см. гайд про npm v12 и allowScripts), а не окно ожидания.
Компрометацию транзитивной зависимости, которая не обновлялась годами и уже сидит в вашем package-lock.json — cooldown работает только на новые обновления, а не задним числом.
Итог
Dependency cooldown — это простой и почти бесплатный слой защиты: он не требует переписывать код, только настройку в dependabot.yml или renovate.json. Дефолтные 3 дня GitHub — разумный компромисс между скоростью получения багфиксов и временем на то, чтобы вредоносный релиз успели заметить и снять с публикации. Для критичных продакшен-зависимостей есть смысл увеличить окно до 7-14 дней вручную — особенно для major-обновлений, которые и так требуют больше внимания при тестировании.