Перейти к содержанию

Известные ограничения

Ограничения собраны на одной странице намеренно: их проще оценить целиком, чем вылавливая по разделам. Для каждого указано, что с ним можно сделать.

Развёртывание и эксплуатация

PostgreSQL — единственная точка отказа

Поставляемые манифесты разворачивают один экземпляр PostgreSQL без репликации. База хранит и данные, и очередь задач, поэтому её потеря останавливает решение целиком.

Что делать: для промышленной эксплуатации подключить внешнюю базу с принятым у вас уровнем доступности — Hub подключается обычными переменными DB_*. Подробнее: Отказоустойчивость.

Разбор отчёта может пойти двумя путями

Backend сохраняет загруженный файл на свой том. Разобрать отчёт способен любой процесс, читающий очередь, — и backend, и worker. От того, кто именно возьмёт задачу, зависит способ разбора:

  • взял backend — файл лежит рядом, отчёт читается потоково, память ограничена;
  • взял worker — файла он не видит и берёт содержимое из базы, разбирая отчёт целиком в памяти.

Worker не видит файл потому, что в поставляемых манифестах тома у процессов разные: в Helm-чарте том worker'а временный и переменная STORAGE_PATH ему не задаётся вовсе, в Docker Compose общий том не объявлен.

Последствия:

  • содержимое каждого отчёта дублируется в базе — оно сохраняется при загрузке независимо от того, кто будет разбирать. При пределе загрузки по умолчанию 500 МБ это заметный вклад в рост базы;
  • пиковая память непредсказуема: один и тот же отчёт может быть разобран экономно или целиком в памяти — в зависимости от того, кому досталась задача;
  • на загрузку, доставшуюся worker'у, в журнал пишется предупреждение о том, что файл не найден на диске. Это ожидаемое поведение, а не неисправность.

Что делать: если объём отчётов заметный — выделить backend и worker общий том с одновременным доступом на запись (ReadWriteMany) и задать worker'у ту же STORAGE_PATH, что и backend. Тогда потоковый разбор работает независимо от того, кто взял задачу. Как временная мера — снизить MAX_UPLOAD_SIZE_MB и сроки хранения отчётов.

Один экземпляр DomainScope

DomainScope не рассчитан на запуск в нескольких экземплярах поверх общей базы: они начнут выполнять одни и те же циклы обследования одновременно. При падении обследование приостанавливается до подъёма.

Что делать: обеспечить перезапуск средствами оркестратора. Уже переданные в Hub находки от простоя не страдают.

Фоновые задачи выполняются «не менее одного раза»

Задача, чей исполнитель погиб после совершения действия, но до отметки о завершении, будет выполнена повторно. Внутри Hub это безопасно, но у внешних систем может проявиться — например, повторным уведомлением.

Что делать: учитывать при построении процессов поверх уведомлений; дубликат сообщения не означает дубликат находки.

Приём отчётов

Превышение лимитов разбора не сообщается вызывающей стороне

Загрузка отчёта асинхронная: сервер отвечает 202 Accepted сразу, а разбор идёт позже. Поэтому лимиты, срабатывающие при разборе, до вызывающей стороны не доходят:

  • отчёт больше 50 МиБ обрезается по этой границе, после чего разбор падает с ошибкой формата — сообщение об ошибке не указывает на размер как на причину;
  • при более чем 100 разделов в отчёте лишние отбрасываются, отчёт при этом считается успешно обработанным. В журнале остаётся предупреждение, в ответе API — нет.

Обратите внимание: предел размера загружаемого файла (MAX_UPLOAD_SIZE_MB, по умолчанию 500 МБ) выше предела разбора (50 МиБ). Файл между этими величинами будет принят и не разобран.

Что делать: снизить MAX_UPLOAD_SIZE_MB до 50, чтобы отказ приходил сразу и с понятной причиной. Крупные отчёты разбивать по разделам на стороне сканера. Проверять итог загрузки по состоянию отчёта, а не только по коду ответа. Полный перечень лимитов: Загрузка SARIF.

Сжатые отчёты не принимаются

Принимаются файлы с расширением .sarif и .json. Архивы, в том числе .gz, отклоняются.

Что делать: распаковывать на стороне системы сборки перед отправкой.

Дедупликация

Находки без CVE на одном порту схлопываются в одну

Если у сетевой находки нет CVE, тождество определяется только узлом, портом и протоколом. Все такие находки на одном порту становятся одной записью независимо от того, какое правило и какой сканер сработали.

Это осознанный компромисс: он убирает основной источник шума при сканировании периметра, но скрывает различия между разнородными результатами на одном порту.

Что делать: там, где различать важно, добиваться от сканера указания CVE. Вклад каждого сканера сохраняется отдельными вкладками в карточке находки, поэтому исходные сообщения не теряются.

Дедупликация работает только внутри продукта

Один и тот же узел, привязанный к двум продуктам, даст две независимые находки со своими жизненными циклами.

Что делать: планировать разбиение на продукты так, чтобы один объект защиты не попадал в несколько продуктов. Если это неизбежно — использовать копирование находок между продуктами, которое связывает их явно.

Автоматизация

Автоматическое закрытие выключено и требует трёх условий

Автозакрытие исправленных находок не работает, пока не включены одновременно глобальный признак, признак в настройках проекта и явное указание при загрузке отчёта. Даже после этого закрытие происходит только после нескольких последовательных проверок.

Это не недоработка, а следствие инцидента: закрытие по одному наблюдению приводило к массовому ложному закрытию настоящих находок.

Что делать: включать осознанно и только для тех проектов, где сканирование покрывает весь объект целиком. Подробнее: Жизненный цикл находки.

Обратная синхронизация с Jira выключена по умолчанию

Перенос статуса из Jira в Hub — опрос по расписанию, по умолчанию отключён. Пока он выключен, закрытие задачи в Jira не закрывает находку в Hub.

Что делать: включить опрос либо настроить приём уведомлений от самой Jira. Подробнее: Jira.

Разбор языковой моделью не принимает решения за человека

Модель меняет состояние только у находок, которых ещё не касался человек. У находки с принятым решением она может добавить пояснение, но состояние не изменит.

Что делать: воспринимать как помощь в разборе, а не как замену аналитика. Порог уверенности настраивается.

Платформа и окружение

Windows не поддерживается

Компоненты рассчитаны на Linux. Развёртывание в Docker на macOS годится только для ознакомления.

OpenShift не проверялся

Поставляемые чарты рассчитаны на k3s и стандартный Kubernetes. Работа в OpenShift не проверялась — вероятны расхождения в политике безопасности контейнеров.

Работа без доступа в интернет требует подготовки

Полностью изолированная установка возможна, но требует ручного переноса образов во внутренний реестр и зеркалирования баз описаний уязвимостей для сканеров. Автоматической процедуры для этого в поставке нет.

Соответствие версий образов

Не для каждой версии опубликованы образы всех компонентов. Перед обновлением убедитесь, что нужный тег существует у всех компонентов, которые вы разворачиваете, и обновляйте их одной версией: интерфейс сравнивает свою версию с версией backend и предупреждает о расхождении. Подробнее: Обновления.

Интерфейс

Язык интерфейса — русский и английский

Другие языки не поддерживаются. Выбор — по заголовку языка браузера.

Массовые операции не поддерживают состояние «ожидание»

Перевод в состояние waiting требует причины и даты для каждой находки отдельно, поэтому массовое изменение с этим состоянием отклоняется.

Что делать: переводить в это состояние поштучно либо использовать для массовой паузы принятие риска на срок.