Управление патчами и уязвимостями
Новый скан выдал 4000 находок, а времени у тебя на сорок. CVSS в одиночку — ловушка: он ранжирует серьёзность в вакууме. Реальная приоритизация умножает серьёзность на экспозицию: достижимо ли, эксплуатируется ли вживую и рядом ли с твоими данными.
Утро понедельника, сканер закончил недельный проход и выдал тебе CSV на 4118 строк. Сорок одна из них — CVSS 9.8 «Critical». У команды на этот спринт максимум сорок инженеро-часов на патчинг, и три из этих критичных сидят во вшитом XML-парсере, который ты даже не вызываешь. А тем временем, зарытая под CVSS 6.5 «Medium», лежит уязвимость десериализации в сервисе аутентификации — смотрит в интернет, с публичным эксплойтом на GitHub, который уже неделю используют вживую. Если патчить сверху вниз по CVSS, ты сожжёшь спринт на недостижимом парсере и отгрузишь пробой auth-сервиса в следующий месяц. Число в строке — это не риск. Риск — это число, умноженное на то, где живёт коробка, и нажимает ли кто-то на самом деле на спусковой крючок.
К концу этого урока ты поймёшь, почему базовый балл CVSS — неверный ключ сортировки, и как ранжировать поток находок по серьёзности на экспозицию, чтобы те сорок часов, что у тебя есть, легли на те сорок багов, которые реально могут навредить.
Два конвейера, а не один
Говорят «патчинг» и имеют в виду две разные машины, скрученные вместе. Разделить их — первый зрелый ход, потому что у них разные входы, владельцы и режимы отказа.
Управление уязвимостями (vulnerability management) — это цикл «обнаружить-и-решить»: инвентаризировать каждый актив, непрерывно сканировать, сопоставлять каждую находку с фидом уязвимостей (NVD, бюллетени вендоров, твой SBOM) и затем решать — патчить, смягчить или принять. Управление патчами (patch management) — это исполнительная рука: получить фикс, протестировать в стейджинге, выкатить в продакшен волнами и проверить, что он действительно встал. Первое отвечает на что не так и важно ли это; второе — на как отгрузить фикс, не сломав прод.
Команды тонут, потому что схлопывают эти два в одно. Они позволяют сырому выводу сканера быть очередью работы, и каждый вторник очередь длиной в 4000 пунктов, а боевой дух испаряется. Дисциплина такова: управление уязвимостями триажит поток до ранжированного, конечного списка с дедлайнами, и только потом управление патчами вытягивает из него. Сканер, сваливающий неранжированные находки в очередь тикетов, — это не программа, это DoS-атака на собственных инженеров.
Почему базовый балл CVSS — неверный ключ сортировки
CVSS даёт каждой уязвимости балл 0–10 из внутренних метрик: вектор атаки, сложность, требуемые привилегии и влияние на CIA. Этот базовый балл по-настоящему полезен — это стандартизированный, вендоронезависимый способ сказать «эта уязвимость, в абстракции, серьёзна». Но слово, которое всех губит, — абстракция. Базовый балл намеренно ничего не знает о твоём окружении: ни достижим ли уязвимый путь кода, ни смотрит ли коробка в интернет или зарыта в трёх подсетях вглубь, ни написал ли кто-нибудь когда-либо к ней эксплойт.
Эмпирика жестока. Исследования раскрытых CVE стабильно находят, что лишь малое меньшинство — порядка 5% — вообще когда-либо эксплуатируются вживую, при этом примерно 60% всех CVE имеют CVSS 7.0 или выше («High» или «Critical»). Сортируй по базовому баллу — и «High/Critical» перестаёт что-либо значить: это бо́льшая часть списка. Сам CVSS говорит, что базовый балл — не балл риска, и его надо комбинировать с окружающим и временны́м контекстом, прежде чем действовать, — указание, которое средняя политика «патчить все Critical за 30 дней» тихо игнорирует.
Поэтому зрелый рефрейм — это умножение, а не поиск по таблице. Риск ≈ серьёзность × экспозиция, где экспозиция — это та часть, которую CVSS опускает:
- Эксплуатируемость вживую — есть ли публичный proof-of-concept? Есть ли она в каталоге Known Exploited Vulnerabilities (KEV) от CISA или высоко по EPSS (модель, предсказывающая вероятность эксплуатации CVE в ближайшие 30 дней)? Баг из KEV используют прямо сейчас; это бьёт теоретическую 9.8 каждый раз.
- Достижимость — вызывается ли уязвимая функция твоим кодом и достижим ли актив оттуда, где стоит атакующий? Критичная уязвимость в зависимости, которую ты импортируешь, но никогда не вызываешь, — латентна, а не живая.
- Радиус поражения — чего касается эта коробка? RCE на коробке с клиентской БД — это другая вселенная по сравнению с тем же RCE на изолированном пакетном воркере.
| Находка | CVSS база | Сигналы экспозиции | Реальный приоритет |
|---|---|---|---|
| RCE десериализации в auth-сервисе | 6.5 (Medium) | Смотрит в интернет, в KEV, публичный PoC, держит хранилище юзеров | P0 — патчить сегодня |
| RCE XML-парсера во вшитой либе | 9.8 (Critical) | Путь кода не вызывается, не в KEV, EPSS ~1% | P3 — в плановом цикле |
| Повышение привилегий в ядре | 7.8 (High) | Только внутри, нужен локальный доступ, нет PoC | P2 — следующая волна |
| Утечка инфо в админ-тулзе | 5.3 (Medium) | Только по VPN, малоценные данные, нет эксплойта | P4 — принять / в бэклог |
Прочти первые две строки вместе: 6.5 обгоняет 9.8. Любая политика, сортирующая по одной колонке CVSS, отгружает ровно неверный порядок.
▸Почему это работает
Почему бы просто не пропатчить всё и пропустить ранжирование? Потому что ёмкость патчинга жёстко ограничена, а у патчинга своя цена. Каждое изменение — это риск регрессии: патч, чинящий CVE, может сломать боевой путь кода, и худшие аварии десятилетия пришли от плохих патчей, а не от непропатченных багов. Тестирование, канареечные выкатки и периодические откаты — всё это съедает те же конечные инженеро-часы. Так что «пропатчить все 4000» — не более безопасный выбор, чем ранжирование; это нефинансированный мандат, который на практике означает, что очередь никогда не пустеет, а действительно срочное ждёт за безобидным. Ранжирование — это как ты тратишь фиксированный бюджет там, где он покупает максимум снижения риска.
SLA превращают приоритет в часы
Ранжированный список без дедлайна гниёт. Механизм, держащий его в движении, — это SLA на устранение: контракт, говорящий, что находка заданного приоритета обязана быть устранена в фиксированном окне, отсчитываемом от обнаружения, и отслеживается. Типичные формы выглядят так: P0/эксплуатируемая Critical → 24–72 часа (или экстренный внеплановый выкат), High → 7–30 дней, Medium → 30–90 дней, Low → следующий плановый цикл или принятие риска.
Две вещи делают SLA реальными, а не театром. Первое: часы стартуют от обнаружения, а не от «когда мы дошли» — так что находка, лежащая нетриажной, уже жжёт свой бюджет, и это та самая нужная тебе пресловутость. Второе: каждому SLA нужен определённый путь исключения: когда ты действительно не можешь пропатчить вовремя (вендорского фикса ещё нет, патч ломает критичный рабочий процесс), ты фиксируешь компенсирующий контроль — правило WAF, сетевую изоляцию, выключенный фичефлаг — и явное, владеемое, ограниченное по времени принятие. SLA без пути исключения не соблюдают; его тихо игнорируют, и тогда у тебя политика, которая врёт. «Среднее время до устранения» против этих SLA — единственная метрика, говорящая, действительно ли программа сужает твоё окно экспозиции или просто плодит тикеты.
Недельный скан вернул 41 находку CVSS 9.8 Critical и, на 6.5 Medium, RCE десериализации в твоём смотрящем в интернет auth-сервисе, которая числится в CISA KEV с публичным эксплойтом. У тебя ~40 инженеро-часов на спринт. Выбери приоритизацию.
Почему сортировка списка находок по базовому баллу CVSS по убыванию — плохая стратегия приоритизации?
У по-настоящему Critical, достижимой уязвимости ещё нет вендорского патча, а окно твоего SLA вот-вот истечёт. Каков верный ход?
Упорядочи конвейер от уязвимости до устранения, от первого шага к последнему:
- 1 Инвентаризировать активы и непрерывно сканировать на находки
- 2 Обогатить каждую находку контекстом эксплойта + экспозиции (KEV, EPSS, достижимость)
- 3 Приоритизировать по серьёзности x экспозиции и назначить дедлайн SLA
- 4 Протестировать фикс в стейджинге, затем выкатить в продакшен волнами
- 5 Пересканировать, чтобы проверить, что патч встал, затем повторить цикл
- 01Почему базовый балл CVSS — неверный ключ для сортировки потока находок, и на что его надо умножить?
- 02Что такое SLA на устранение, почему часы должны стартовать от обнаружения и что делает его путь исключения?
Патчинг — это на самом деле два конвейера: управление уязвимостями обнаруживает, обогащает и ранжирует находки до конечного списка; управление патчами тестирует, катит и проверяет фиксы. Команды тонут, когда схлопывают эти два и позволяют сырому скану — 4000 строк каждый вторник — быть очередью работы. Кардинальная ошибка — сортировать по базовому баллу CVSS: это серьёзность в вакууме, ~60% CVE — High/Critical, и лишь ~5% когда-либо эксплуатируются, так что колонка почти ничего не сортирует. Реальный приоритет — серьёзность × экспозиция: эксплуатируется ли вживую (CISA KEV, EPSS), достижим ли путь кода и каков радиус поражения? — поэтому смотрящая в интернет 6.5 из KEV в твоём auth-сервисе обгоняет 9.8 в коде, что ты никогда не вызываешь. Привяжи SLA на устранение, чьи часы стартуют от обнаружения и чей путь исключения позволяет зафиксировать компенсирующий контроль и владеемое, ограниченное по времени принятие, когда патча нет, затем проверь пересканированием, а не предположением. В следующий раз, когда сканер выдаст тебе 4000 находок, твой первый вопрос — не «где самый высокий CVSS», а «что из этого достижимо, эксплуатируется и рядом с моими данными».
Практика
Начни сверху. Задачи идут от простого к сложному: вспомнить факт, применить к случаю, затем senior-уровень. Открой, попробуй, потом открой ответ.
Что-то непонятно?
Задай вопрос по этому уроку. Вопросы анонимны и попадают напрямую автору — урок станет лучше.
Примени это
Примени этот урок в реальном проекте.