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

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

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

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

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 и сроки хранения отчётов.

Очистка отчётов зависит от того, какому процессу досталась задача

Та же причина, что у разбора, — тома у backend и worker'а разные, — но последствие другое и заметное не по памяти, а по диску: процесс без тома файлов не находит, а отсутствие файла для него штатный исход.

В 0.33 такой прогон не выдаёт себя за успешный:

  • задача, доставшаяся процессу без тома, откладывается (снузится), чтобы её взял процесс с томом;
  • если тома нет ни у одного процесса дольше отведённого окна, чистка базы всё равно выполняется, а недостижимость файлов пишется в журнал ошибкой с подсказкой проверить монтирование и STORAGE_PATH;
  • принадлежность тома определяется по факту — видит ли эта файловая система файлы самых свежих отчётов, — а не по настройке, которую можно выставить неверно.

Что это всё ещё не делает: файлы удаляются только там, где том есть. На инсталляции, где worker не видит тома, чистка идёт медленнее — прогон откладывается до backend'а.

Что делать: тот же общий том с ReadWriteMany и та же STORAGE_PATH у worker'а, что и в предыдущем ограничении, — одна настройка закрывает и разбор, и очистку.

Каталог плагинов в закрытом контуре стучится наружу

Официальный источник hub-official заводится при обновлении включённым и указывает на gitlab.com. Проверка отзывов подписей обходит все включённые источники при старте процесса и раз в сутки, поэтому в сети без выхода наружу это даёт ежедневную неудачную попытку соединения.

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

Что делать: переставить адрес каталога на своё зеркало либо удалить запись — удалённая при следующем обновлении не вернётся. Подробнее: Официальные плагины.

Один экземпляр 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. Вклад каждого сканера сохраняется отдельными вкладками в карточке находки, поэтому исходные сообщения не теряются.

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

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

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

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

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

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

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

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

Закрытие задачи доходит до Hub не мгновенно

Каналов обратной связи два: вебхук от трекера и опрос статусов по расписанию (по умолчанию раз в час). Вебхук требует, чтобы трекер дотягивался до Hub, — в закрытом контуре работает только опрос, и находка закрывается с задержкой до интервала опроса.

Недоступная или удалённая задача закрытием не считается: потеря задачи ничего не говорит об уязвимости.

Что делать: настроить вебхук там, где он возможен, и оставить опрос как страховку. Подробнее: Учёт задач.

Перенос настроек каналов Mattermost и MAX — только запросом к API

При обновлении на 0.33 эти каналы переехали в плагины, а перенос их настроек выполняется административным запросом: интерфейса у него нет. До переноса уведомления по этим каналам не отправляются.

Что делать: пройти порядок из раздела Обновление на 0.33.

Нативные плагины требуют явного разрешения

Каналы уведомлений и провайдеры задач — нативные плагины (Tier 2). На свежей инсталляции официальный каталог подключён, но исполнение нативных плагинов не разрешено, поэтому они видны и не ставятся.

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

Ссылка на удалённый продукт в копировании находок не убирается сама

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

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

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

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

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

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

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

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

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

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

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

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

Не для каждой версии опубликованы образы всех компонентов: они выпускаются независимо, и совпадение номеров — не правило, а совпадение (на 0.33 версии сошлись).

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

Интерфейс

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

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

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

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

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