Добрый день, читатели Хабра!
Представляем вашему вниманию историю о том, как из маленькой идеи вырос полноценный продукт, предлагающий безопасную разработку как сервис. Также расскажем о проблемах и ошибках, которые возникали на этом пути, и поделимся планами на будущее.
Рождение идеи
Зачастую все лучшие идеи рождаются в расслабленной обстановке. Apsafe не исключение: после большого количества пентестов «белым ящиком» и аудитов процессов безопасной разработки Женя и Сережа пришли, попивая кофе на кухне, к идее создания сервиса. Женя мастерски владел словом и навыками в уже набравшей популярность методологии DevSecOps, Сережа был не только пионером компании, но и профессионально занимался тестами на проникновение. Первоначальная концепция была проста как мир: а почему бы не сделать DevSecOps как сервис?
DevSecOps (Development/Security/Operations) — это культура и методология, содержащая конкретный набор практик и цели, приуроченные к внедрению и улучшению процессов безопасности на каждом из этапов жизненного цикла программного обеспечения.
Опыт в аудитах процессов разработки привел к следующим выводам:
компании хотят закрыть потребности/требования по безопасной разработке и устранять уязвимости;
внедрять собственные процессы в компании, набирать команду — сложно, дорого и нет полноценной необходимости.
Собрав выводы воедино, команда, пока состоящая из двух человек, решила проверить концепцию, опросив ключевых заказчиков. Идея им понравилась, но вопросы все-таки возникли. Ключевым стал: «А как это будет выглядеть?».
В ходе дискуссий пришли к целевой реализации в облаке, потому что это:
дешевле закупки собственного сервера на начальных этапах: в первое время не было понятно, как наращивать клиентскую базу;
легко масштабировать: облако позволяет расширять ресурсы из единой точки;
нет необходимости расширять штат сотрудников, обслуживающих железо: нужен Managed Kubernetes.
С учетом этих размышлений Женя принял решение разработать минимально жизнеспособный продукт (Minimal Viable Product, MVP) в Яндекс Облаке, одновременно проводя необходимые исследования — нужны были цифры, чтобы говорить с «бизнесом» на одном языке.

На картинке выше показана схема реализации MVP, именно так задумывалась работа сервиса. Сейчас всё работает совершенно по-другому: появились как Runtime Engine Policy, так и L3/L7-фильтрации. Из-за NDA схему текущей реализации прикладывать не будем :)
Суть экосистемы
Что значит «экосистема безопасной разработки»? Это полный путь разработки от постановки задачи до развернутого приложения, где каждая из стадий защищена.
Мы стараемся закрывать все потребности заказчиков в рамках парадигмы DevSecOps — от консультаций по документам и анализу процессов до полноценного триажа уязвимостей приложения.
Реализация и первые пилоты
Прошло время, Сережа ушел из компании, а Женя продолжил работу над созданием продукта. Но не один — идею одобрили, выделив ресурсы на команду и реализацию. Первых сотрудников «схантили» внутри компании: из направления аудитов информационной безопасности взяли аналитика безопасной разработки, а из департамента системной интеграции пришел инженер, который готовил техническую реализацию продукта и продумывал нюансы.
Тезисно концепцию мы представляли так:
заказчик пушит только изменения;
pipeline со всеми анализаторами запускается сразу после пуша;
заказчику должно быть удобно следить за зависимостями, используемыми при разработке программного обеспечения (далее — ПО);
заказчик всегда может посмотреть актуальные для своего приложения уязвимости.
Схема процесса выглядела так:

Состав ПО для первых пилотов был следующим:
InfraGitlab — управление количеством сущностей Apsafe, в нем содержится вся актуальная информация в формате Infrastructure-as-Code (IaC);
ApsafeGitlab — сервер Version Control System (VCS), в который заказчик отправляет код, в нем же запускается security-pipeline;
ApsafeSCA — хранение и анализ зависимостей, реализацией стал на первое время DependencyTrack;
ApsafeASOC — хранение и оркестрация уязвимостей, мы используем DefectDojo и по сей день.
Первые проблемы
Задумавшись над тем, как стопроцентно гарантировать разграничение экземпляров Apsafe, мы пришли к выводу, что необходимо это делать и на уровне внутри сети K8S, и на «внешнем контуре». Конкретные реализации сюда писать не будем, но мы используем следующие инструменты и практики:
Istio — разграничение как внутри Kubernetes namespace, так и контроль за исходящим трафиком;
Kyverno — ограничение ресурсов при запуске;
Web Application Firewall as Yandex Cloud (YC) Service — анализ и разграничение доступов для заказчиков по Classless Inter-Domain Routing (CIDR).
Проектируя Apsafe, мы подумали над дедупликацией уязвимостей: хотели каждую проверку создавать новую сущность, в рамках которой были бы все сканирования. В Defectdojo эта потребность закрывается достаточно быстро: по умолчанию дедупликация при создании нового engagement происходит в рамках этого же engagement, но при его создании есть флаг DEDUPLICATION_ON_ENGAGEMENT, позволяющий включить дедупликацию на уровне product. Это решение мы приняли, потому что у нас такие процессы и абстракции, мы встречали и реализации, когда product=application, engagement=repository — всё зависит исключительно от ваших пожеланий и процессов.
Недавно, посмотрев на инфраструктурную схему, мы поняли, что заказчик с помощью тех привилегий, которые ему выдаются, может заменить .gitlab-ci.yml, существующий в репозитории. Эта проблема приводит к ApsafeGitlab как к вектору атаки, а там можно делать критичные вещи: от запуска привилегированного контейнера с выходом на хост (потенциально) до попыток переместиться в другой K8s namespace.
Осознав критичность, бросили все дела и ограничили запускаемые образы по названиям и registry, параллельно сканируя images на наличие уязвимостей. Все образы буквально недавно были пересобраны нами, чтобы уменьшить периметр атаки. Закрывали мы это на уровне Admission Controller, так как это общее решение. Все еще висит issue в GitlabCE, где мы просим возможность писать собственные правила для валидации gitlab-ci :( Помимо прочего, мы вынесли security-pipeline в отдельную группу и отключили gitlab runner в «группе Заказчика», таким образом при добавлении .gitlab-ci.yml мы защищены от Pipeline Poisoned Execution. Сам security-pipeline запускается механизмом trigger pipeline.
Долгое время управлять YC Managed Databases приходилось с помощью веб-интерфейса — terraform-провайдера просто не существовало. Отправляли запросы, недавно провайдер реализовал Terraform, и мы переписывали часть логики в создании экземпляра Apsafe.
Другая проблема пришла к нам год назад: на одном из проектов было несколько ресурсов, которые необходимо было сканировать с помощью Dynamic Application Security Testing (DAST). Если запускать их параллельно, то 4 активных сущности OWASP Zed Attack Proxy (ZAP) съедали больше 7 гигабайт ОЗУ, после чего некоторые запуски могли в какой-то момент просто падать. Их убивал OOM Killer — механизм ядра Linux, который при исчерпании доступной памяти принудительно завершает отдельные процессы на сервере для освобождения RAM. Сначала пытались как-то оптимизировать запуск, замерять ресурсы и повышать лимиты, но потом решили изменить подход. Согласовав увеличение времени, доступное для сканирования, мы начали запускать DAST последовательно для каждого ресурса.
Взгляд в будущее
Мы прошли многое и не собираемся останавливаться. Помимо улучшения самого Apsafe, исправления некоторых моментов и полной автоматизации создания экземпляров, мы параллельно двигаемся в сторону закрытия других потребностей.
Сейчас концентрируемся на полной экосистеме безопасной разработки и автоматизируем собственные проверки, которые до этого делали «руками».
Создаем Mobile Application Security Testing (MAST) — сервис по анализу мобильных приложений на базе Android/iOS, который будет поддерживать различные виды анализа для запуска как в ручном, так и в автоматическом режимах.
Создаем Fuzzing-ферму — сервис для автоматизации fuzzing-тестирования за счет централизованного управления, бо́льших ресурсов и, соответственно, эффективности.
Разрабатываем Quality/Security Gate — в зависимости от прохождения порога будет останавливать pipeline заказчика.
Развиваем DAST — создание собственных правил для DAST-анализа.
Автоматизируем эксплуатацию DAST — осуществление проверки отчетов DAST автоматически с помощью средств эксплуатации.
Автоматизируем проверку Static Application Security Testing (SAST) — генерация эксплойтов для найденных уязвимостей и проверка их на тестовом стенде, что позволит уменьшить время для проверки AppSec-специалистами.
Встраиваем Machine Learning (ML) в SAST — уменьшение false positive за счет контекстного анализа кода с помощью обученной модели.
Создаем Large Language Model (LLM) для AppSec — ассистент, который живет в контексте приложения и может рассказать про уязвимые части, уменьшая трудозатраты AppSec-специалистов.
В этой статье мы рассказали о том, как появилась наша платформа непрерывного анализа защищенности Apsafe, и с какими сложностями мы столкнулись на этом пути.
Что вам еще было бы интересно узнать об Apsafe?
Авторы:
Дмитрий Зайцев @sonderno, специалист по инфраструктурной безопасности направления безопасной разработки УЦСБ
Анастасия Камалова, пресейл-инженер направления безопасной разработки УЦСБ