Известные ограничения¶
Ограничения собраны на одной странице намеренно: их проще оценить целиком, чем вылавливая по разделам. Для каждого указано, что с ним можно сделать.
Развёртывание и эксплуатация¶
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 требует причины и даты для каждой находки
отдельно, поэтому массовое изменение с этим состоянием отклоняется.
Что делать: переводить в это состояние поштучно либо использовать для массовой паузы принятие риска на срок.