Жизненный цикл находки¶
Находка — центральная сущность Hub. Эта страница описывает, как из результата работы сканера получается находка, что считается одной и той же находкой при повторных сканированиях, какие состояния она проходит и как считается срок устранения.
Из чего складывается находка¶
Отчёт сканера содержит набор результатов. Каждый результат Hub приводит к общему виду независимо от того, каким инструментом он получен:
| Поле | Откуда берётся |
|---|---|
| Правило | Идентификатор сработавшего правила из отчёта |
| Местоположение | Файл со строками, либо узел с портом и протоколом, либо адрес веб-ресурса |
| Критичность | Явное поле отчёта, иначе уровень результата, иначе уровень правила, иначе INFO |
| Описание | Текст сообщения из отчёта |
| Сканер и его версия | Из отчёта либо из параметров загрузки |
| Ревизия | Идентификатор коммита — из отчёта, заголовка, поля формы или параметра запроса |
Уровни критичности: CRITICAL, HIGH, MEDIUM, LOW, INFO.
Дедупликация¶
Ключевой вопрос: если тот же сканер отработал завтра, а послезавтра то же самое нашёл другой сканер — это одна находка или три? Hub считает, что одна, и определяет тождество по правилу и местоположению. Имя сканера в расчёт не входит намеренно: разные инструменты по-разному называют одну и ту же проблему.
Для каждого результата считается хеш; результаты с совпавшим хешом внутри одного продукта — одна и та же находка.
| Тип находки | Что определяет тождество |
|---|---|
| Код: файл, строки, фрагмент | Продукт + правило + местоположение в файле |
Веб-ресурс: адрес начинается с http:// или https:// |
Продукт + правило + полный адрес |
| Сетевая: есть узел или адрес, и это не веб-ресурс, и известен CVE | Продукт + CVE + узел с портом и протоколом |
| Сетевая, CVE неизвестен | Продукт + узел с портом и протоколом |
Из последних двух правил следуют два практических вывода:
- Один и тот же CVE на одном и том же порту — одна находка, сколько бы сканеров его ни нашли и как бы по-разному они ни называли своё правило.
- Несколько находок без CVE на одном и том же порту схлопываются в одну «аномалию на порту». Это осознанный компромисс: он убирает шум, но скрывает различия между такими результатами.
Дедупликация работает в пределах продукта. Тот же узел, привязанный к двум продуктам, даст две независимые находки.
Что не влияет на тождество
Расширенные поля отчёта — состояние относительно базовой линии, признак подавления, вид результата, отпечатки — сохраняются и доступны для фильтрации, но в расчёт тождества не входят. Иначе первая же загрузка отчёта от сканера, начавшего их выставлять, продублировала бы все существующие находки.
Состояния¶
Всего десять состояний. Новая находка создаётся в состоянии new.
| Состояние | Смысл |
|---|---|
new |
Только что обнаружена, никто не смотрел |
renewed |
Ранее закрытая находка обнаружена снова |
needs_review |
Требует повторного решения — например, истёк срок принятия риска |
in_progress |
Взята в работу |
confirmed |
Подтверждена как настоящая |
waiting |
Ожидает внешнего события; таймер срока приостановлен |
risk_accepted |
Риск принят на срок |
wont_fix |
Решено не исправлять |
false_positive |
Ложное срабатывание |
fixed |
Исправлена |
Состояния сгруппированы — группы используются в счётчиках и на дашбордах:
- Требуют внимания:
new,renewed,needs_review,confirmed,in_progress,waiting. - Открытые в широком смысле: то же плюс
risk_acceptedиwont_fix— проблема существует, но решение по ней принято. - Закрытые:
false_positiveиfixed.
flowchart TD
New["new<br/>обнаружена"]
Review["needs_review<br/>нужно решение"]
Conf["confirmed<br/>подтверждена"]
Prog["in_progress<br/>в работе"]
Wait["waiting<br/>ожидание"]
Risk["risk_accepted<br/>риск принят"]
Wont["wont_fix<br/>не исправляем"]
FP["false_positive<br/>ложное"]
Fixed["fixed<br/>исправлена"]
Renew["renewed<br/>обнаружена снова"]
New --> Conf
New --> FP
New --> Risk
Conf --> Prog
Prog --> Wait
Wait --> Prog
Prog --> Fixed
Conf --> Wont
Risk --> Review
Wait --> Review
Review --> Conf
Review --> FP
Fixed --> Renew
Renew --> Conf
classDef open fill:#dbeafe,stroke:#2563eb,stroke-width:2px,color:#111827
classDef pause fill:#fef3c7,stroke:#d97706,stroke-width:2px,color:#111827
classDef closed fill:#dcfce7,stroke:#16a34a,stroke-width:2px,color:#111827
class New,Conf,Prog,Review,Renew open
class Wait,Risk,Wont pause
class FP,Fixed closed
Схема показывает типичные переходы, а не полный список: интерфейс позволяет перевести находку в любое состояние вручную.
Состояния с датой пересмотра¶
Два состояния не бывают вечными:
risk_accepted— принятие риска с датой, до которой оно действует. Периодическая задача возвращает такие находки вneeds_review, когда дата проходит.waiting— ожидание внешнего события. Обязательны причина и дата, до которой действует ожидание; дальше чем на 30 суток вперёд её задать нельзя. По истечении находка возвращается вneeds_review, а причина и дата очищаются.
Состояние waiting нельзя назначить массово: причина и дата задаются для
каждой находки отдельно, поэтому массовое изменение с таким состоянием
отклоняется.
Сроки устранения¶
Таймер запускается при взятии находки в работу. Срок зависит от критичности и задаётся в настройках проекта. Значения по умолчанию для нового проекта:
| Критичность | Срок по умолчанию |
|---|---|
CRITICAL |
7 суток |
HIGH |
14 суток |
MEDIUM |
30 суток |
LOW |
90 суток |
Для INFO срок по умолчанию не задан.
Пауза — это действительно пауза, а не пометка. При переходе в состояние,
которое не может нарушить срок (waiting, risk_accepted, needs_review),
фиксируется момент остановки. При возврате в работу срок сдвигается ровно на
время простоя — проведённое в ожидании время дедлайн не съедает.
Проверка сроков выполняется ежечасно. Она находит находки с приближающимся
и с нарушенным сроком и ставит задачи на оповещение. При переходе в
завершающее состояние (fixed, wont_fix, false_positive) открытые
нарушения срока закрываются.
Автоматическое закрытие после исправления¶
Hub умеет сам закрывать находки, которых больше нет в результатах сканирования. Механизм намеренно осторожен: неполное или сбойное сканирование не должно закрыть массив настоящих находок.
Автозакрытие требует одновременного выполнения трёх условий:
- возможность включена глобально (
FEATURE_AUTO_VERIFY_FIXES); - она включена в настройках конкретного проекта;
- при загрузке отчёта явно передано, что этот отчёт пригоден для проверки
исправлений (
verify_fixes=true).
Даже когда все три условия выполнены, закрытие происходит не с первого раза:
- отсутствие находки проверяется несколько раз подряд внутри одной проверки (по умолчанию 3 попытки); любой ответ «на месте» или «неопределённо» немедленно оставляет находку открытой;
- закрытие происходит только после нескольких последовательных проверок, давших «отсутствует» (по умолчанию 3). Любое обнаружение сбрасывает счётчик.
Почему так сложно
Ранняя версия закрывала находку по одному наблюдению «отсутствует». На работающей установке это привело к массовому ложному закрытию: значительная часть находок вернулась при следующем сканировании, причём среди закрытых оказались настоящие открытые сервисы. Оба уровня — повторы внутри проверки и кворум между проверками — добавлены как реакция на этот случай и по отдельности недостаточны.
Отдельно существует перепроверка вторым источником: находка считается исправленной, только если это подтвердили два независимых механизма. Есть предел числа закрытий в час на проект, чтобы сбой одного источника не привёл к лавине. Подробнее: Ручная перепроверка.
Несколько источников у одной находки¶
Когда одну и ту же проблему нашли несколько сканеров, находка остаётся одна, но сохраняет вклад каждого источника. В карточке находки они показаны отдельными вкладками: какой сканер, когда сканировал, какой CVE и какую оценку сообщил, каким было исходное описание.
Это важно при разборе: расхождение оценок между сканерами — сам по себе сигнал, и он не должен теряться при слиянии.
Группы находок¶
Однотипные находки можно объединить в группу и работать с ней как с целым: изменение состояния распространяется на всех участников. При этом каждый участник обрабатывается как отдельная находка — со своей записью в журнале действий, своим таймером срока и своими последствиями вроде создания задачи в Jira.
Журнал действий¶
Изменения находок фиксируются в журнале действий: кто, что и когда изменил. Журнал — источник данных для отчётов руководству, в том числе для расчёта среднего времени устранения. Действия, выполненные автоматически, отличаются от действий пользователя.