Для тех, кто запускает несколько веб-приложений (разные фреймворки) малой командой и хочет исправить уязвимости зависимостей (CVE) по-настоящему, раз и навсегда. Без шагов атаки — только практика исправления, закрепления исправлений и наблюдения. Про тип инцидента, который часто это запускает, см. заброшенная публичная RCE и мошеннические счета.
Взгляд этого сайта: малые команды остаются в безопасности за счёт двух дисциплин
В малой команде работает не яркий инструментарий, а две дисциплины: 1) автоматическое обнаружение изменений (оповещать только о новых уязвимостях) и 2) локально→push→деплой (продакшен принимает, никогда не правит). Этот сайт работает так же: аудит зависимостей (pnpm audit) перед каждым деплоем плюс ежедневный cron, с push-to-deploy, доставляющим в продакшен. Настроить оповещения, которые продолжают работать, вместо разового исправления — самый дешёвый подход, который держится долго.
Сначала определите четыре условия «готовности»
Это не даёт объявить «готово» слишком рано. Решите заранее: пока не сойдутся все четыре, это незавершённо.
1. Скан
перевести состояние в цифры
2. Фикс
исправление не-dev крит/высоких в источнике
3. Изоляция/передача
сделать неисправимое явным
4. Мониторинг
наладить ежедневное обнаружение изменений
1. Скан: посчитайте, что есть сейчас
Сначала увидьте, что и где, машинно. Ручные разовые проверки всегда срываются.
Автоматически находите lock-файлы и сканируйте
composer.lock / package-lock.json / pnpm-lock.yaml и прогоняйте их ежедневно через сканер с открытым кодом (osv-scanner или pnpm audit). Он лишь читает lock-файлы, так что нагрузка крошечная.Знайте, что серьёзность — не одно число
Исключайте шум С записанной причиной, а не игнорированием
2. Фикс: обновите саму уязвимую версию
Временная мера, скрывающая симптом, и устранение настоящей причины — разные задачи. Сделайте обе, чтобы закончить.
Только сокрытие симптома (причина остаётся)
- блокировать только «подозрительно выглядящие» запросы на обратном прокси
- симптом прекратился, значит назвать «разобрались»
- уязвимая зависимость остаётся — RCE всё ещё можно эксплуатировать
Устранение причины (правильно)
- обновить уязвимую зависимость до исправленной версии
- после обновления убедиться, что сигнатура исчезла из логов
- считать временную меру и настоящее исправление двумя разными задачами и делать обе
Проверяйте мажорные обновления сборкой ДО продакшена
В отличие от патча, скачок мажорной версии (фреймворк 14→15, UI-кит 4→6 и т. п.) несёт ломающие изменения. Обновление без проверки, ломающее прод-сборку, роняет сервис. Поместите изменённый исходник в идентичную проду среду выполнения (контейнер с той же версией Node/PHP) и добейтесь полностью зелёной сборки/проверки типов до push. Устраняйте ошибки по одной (codemod sync→async, многострочные строки CSS-классов, упразднённое глобальное пространство типов и т. п.). Если старый контейнер продолжает работать, при сбое откат проходит без простоя.
Убедитесь, что следующий деплой не отменит исправление
Идеальное исправление стоит ноль, если следующий деплой его стирает. Это самая частая ошибка.
Не коммитьте в продакшен-дереве
Стандартизируйте одно направление: локально→push→деплой
Не доверяйте HTTP 200 как «здоровью»
curl | grep), нет ли новых ошибок в логах, и пройдите по динамическим маршрутам (на БД, с параметрами), а не только по главной. Кэши могут задержать изменение, так что подождите или сначала очистите.3. Изоляция/передача: запишите то, что не можете исправить
Не всегда можно исправить всё сейчас. Хитрость — никогда не оставлять «не могу исправить / не моя зона / не используется» неопределённым.
Осиротевший/EOL код: изолируйте ПЕРЕД удалением
Сначала убедитесь, что на него реально нет ссылок
Явно передавайте то, что не можете исправить
4. Мониторинг: наладьте ежедневное обнаружение изменений
Теперь, наконец, поставьте механизм оповещения. Без него сделанное исправление не сообщит вам, когда оно повторится.
Оповещайте о НОВОМ, а не обо всём каждый день
Сравнивайте результаты скана с предыдущим прогоном (файлом состояния) и уведомляйте только при появлении нового критического/высокого. Одно и то же содержимое каждый день начинают игнорировать (усталость от оповещений). Сводите в одно письмо (новые / устранённые / текущие) по ежедневному cron. Даже шаред-хостинг нормально тянет один бинарник сканера + cron (нагрузка — миллисекунды; добавьте nice для спокойствия).
API-ключи и SSH-ключи, которые инвентаризация тоже находит
Реальное закрытие CVE часто выявляет и проблемы, не связанные с зависимостями. Две частые — файл секрета, оставленный в публичной директории (старый токен в веб-корне; если он из общего шаблона, у каждого сайта та же проблема) и корневой ключ, выданный среде, которую можно скомпрометировать. Оба создают паттерн «одна утечка — всё», так что проверяйте их в том же проходе (каждое заслуживает отдельного разбора). По основам секретов см. безопасное хранение секретов и базовый чек-лист.
Читать дальше
- CVE-2026-111793 Openwave: запись в KEV при низкой оценке
- Пример (ежемесячный день патчей): SAP Security Patch Day, ноябрь 2026 (четыре уязвимости с CVSS 10.0)
- Реальный случай: CVE-2026-123551: раскрытие токенов сеанса в OpenAM (обновление плюс отзыв сеансов)
- Пример: Уведомление безопасности Jenkins (28 октября 2026 года, 15 проблем)
- Решение: Какую CVE закрывать первой — CVSS, EPSS и KEV
- Мониторинг зависимостей: установка и использование osv-scanner · не отставать от CVE
- Инцидент: заброшенная публичная RCE и мошеннические счета
- Эксплуатация: продакшен только на приём / самостоятельный Git против GitHub
- База: базовый чек-лист безопасности
- Инцидент: программа-вымогатель у Capcom (2020) (входом стало заброшенное старое VPN-устройство)
- Инструмент: поиск CVE / KEV (CVSS, EPSS и признак активной эксплуатации на одном экране)
- Защита по типам: уязвимости загрузки файлов — как исключить веб-шеллы и RCE на уровне архитектуры