Привет, Хабр! Меня зовут Нияз Кашапов, я AppSec Lead в Купере. Недавно я рассказывал на ecom.tech Information Security meetup, как выстраивается процесс написания безопасного кода и разбора срабатываний статических анализаторов. Эта статья — изложение моего выступления с дополнительными комментариями. Я опишу подход, к которому мы пришли, и открою секрет, как мотивировать разработчиков смотреть свой код на безопасность.

О технической стороне организации безопасной разработки в блоге Купера уже рассказывал DevSecOps Lead Максим Коровенков:

Вы таки внедрили сканеры безопасности в пайплайны — на этом все?

Через тернии к звёздам: строим SSDLC на OpenSource-компонентах

Душный ИБ и все прелести жизни

Самая большая проблема «классической» информационной безопасности в компаниях состоит в том, что никто не хочет общаться с представителями ИБ. Просто потому, что с вероятностью 80% эти специалисты задушнят, запретят что-то новое и суперклассное, которое принесет компании миллионы рублей и сделает мир лучше.

Чаще всего классический ИБ действительно все запрещает. В начале карьеры я работал в банке. Каждый релиз сопровождался заявкой, которую в любой момент могли завернуть обратно, так как не был предоставлен документ с результатами сканирования и тестирования сервиса. Заявка рассматривалась долго, и это очень бесило продактов и менеджеров, которым нужно было, как обычно, провести релиз еще вчера.

Для Waterfall-модели релиз через заявку и ПСИ (приемо-сдаточные испытания) возможен. Но что делать если сервисов больше ста, а сервисы могут обновляться по несколько раз за неделю?

Ответ простой: релизы не должны зависеть от ручных действий. Все следует автоматизировать, в том числе и безопасность.

О том, как устроены наши пайплайны, можете почитать в предыдущей статье. Особое внимание стоит уделить Security Quality Gate — той самой бездушной машине, которая не пускает сервис в прод, если сканеры безопасности кода нашли уязвимости.

Можем ли мы верить SAST?

Инструменты достаточно часто выдают False Positive (ложноположительные) результаты, особенно SAST и его подвиды — это факт.

SAST — параноик, который цепляется за все, что похоже на уязвимость. Поэтому нужно внимательно смотреть отчеты и проверять, действительно ли есть уязвимости или сканер просто триггернулся на слово «key» (некоторые сканеры уже лет шесть никак не могут пофиксить эту проблему).

Кто же должен смотреть результаты SAST-инструментов чтобы отсеять False Positive?

Ответ вроде очевидный — Application Security Engineer. Но почему Application Security? Из-за глубоких знаний? Разработчик, который создал и поддерживает сервис, гораздо лучше понимает, что к чему. Не сто́ит забывать, что безопасность является частью качества продукта: если QA находит багу, то фиксит ее разработчик; если юнит-тест отваливается, приходит разработчик. Уязвимости исправляет тоже разработчик, а это значит, что первичную обработку срабатываний статических сканеров разработчик может делать самостоятельно.

Триажим удобно и (не)быстро

Когда я только начинал работать AppSec-специалистом, мое утро начиналось не только с кофе, но и с разбора новых срабатываний сканеров. Все происходило на веб-страничке самого сканера, надо было всего лишь смотреть в таблицу и нажимать на кнопку «Отклонено» или «Подтверждено». Каждый день одно и тоже, для десятка проектов. И это только один инструмент.

Тогда про DevSecOps не знали, для прокрытия требований безопасности хватало одного сканера и ручных проверок со стороны ИБ. Однако сейчас инструментов стало сильно больше. Намного эффективнее использовать несколько инструментов с открытым исходным кодом, чем покупать монструозное проприетарное решение и пытаться с ним как-то ужиться.

О том, как мы подружили инструменты, уже писали. И что в итоге сделали — тоже. Но напомню, что изначально мы складировали все результаты в DefectDojo и пытались внутри него отмечать ложноположительные срабатывания сканеров. К сожалению, DefectDojo не смог переварить такое большое количество проектов и их сканирований. Постоянные 500-е ошибки и ожидание ответов по несколько минут совершенно не упрощали задачу.

Вроде кто-то уже научился готовить DefectDojo, об этом можете послушать доклад, который звучал на нашем DevSecOps Meetup. Но у нас не было ресурсов переписывать и оптимизировать это решение под себя. А платной версии DefectDojo еще не было...

Имея центральное хранилище, не так просто делегировать разбор срабатываний сканеров на разработчиков. Надо подключать ADFS/Keycloak, делить доступы, всех учить пользоваться порталом и т. д. Да и новый инструмент может попросту «не зайти» разработчикам. У кого-то доступ потерялся, кто-то забил, кому-то лень.

В идеальном мире, где Shift Left победил, сканеры работают непосредственно в IDE, разработчик может увидеть потенциальную проблему на стадии написании строчки кода. Но в реальности реализовать такое очень сложно. Особенно когда в компании используются разные стеки технологий, IDE, процессы работы с кодом. Даже Visual Studio не всемогущий. Хотя IntelliSense отображает потенциальные проблемы безопасности в коде, сканеры находят более хитрые проблемы.

В итоге мы отказались от DefectDojo и стали использовать то, что объединяет нас всех: Git и CI/CD-конвейеры. Разбор найденных уязвимостей проводим через вывод в логи джобы.

Для SAST это:

  • Ссылка на файл

  • Тип уязвимости

  • Критичность

  • Уязвимый код

  • Идентификатор

  • Дополнительная информация об уязвимости

  • Название сканера, нашедшего потенциальную проблему

Вывод в job-output
Вывод в job-output

Для SCA/OSA-сканеров вывод чуть отличается. Показываются библиотеки, версии и информация об уязвимости (CVE):

Много CVE, но реально эксплуатируемых — единицы
Много CVE, но реально эксплуатируемых — единицы

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

Что же делать с этим разработчику?

Может быть, пойти в куперы… Шутка. Или нет…
Может быть, пойти в куперы… Шутка. Или нет…

Сканеры выдают три типа находок, и вот какие действия ожидаются в связи с ними от разработчиков:

  • False Positive — понимаем, что сканер ошибся, и исключаем «уязвимость» из списка файндингов.

  • True Positive — понимаем что уязвимость существует. Заводим задачу на фикс. Исключаем находку из списка на время фикса.

  • Unknown — идем к AppSec BP, чтобы понять, что это такое и как исправить.

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

Разработчики для своих проектов пишут исключения в виде YAML-файлов в едином репозитории команды Application Security. Подробно уже рассказано в первой статье.

Файл с исключениями для одного проекта
Файл с исключениями для одного проекта

Все изменения проходят ревью у AppSec BP. Просто так залить их в мастер не удастся. Так что защита имеется.

Merge Request для исключений
Merge Request для исключений

Мотивация быть лучше

Не всегда разработчики готовы к тому, чтобы безопасники им что-то делегировали. Так что используем метод кнута и пряника во всей красе.

Начнем с мягких методов мотивации:

Внедряем практику → рассказываем командам → хвалим тех, у кого получается → показываем пример другим.

Мы взяли за основу TMM (Team Maturity Model), которая оценивает зрелость команд с разных точек зрения, в том числе по безопасности разработки.

Оценка зрелости строится на четырёх уровнях:

  • 0 — ничего нет

  • 1 — что-то есть

  • 2 — есть что-то хорошее

  • 3 — все отлично

Уровень 0

Команда не знает о существовании группы Application Security и не знает, кто такой AppSec Business Partner. У команды отсутствует взаимодействие с командой AppSec.

Уровень 1

Команда выстраивает процесс взаимодействия с AppSec. Уровень подтверждается закрепленным бизнес-партнером, а в случае его отсутствия — менеджером AppSec.

Уровень 2 (базовая линия)

Команда учитывает все требования безопасности к архитектуре и разработке сервисов, руководствуется безопасными паттернами, если они описаны командой AppSec.

Уровень 3

Команда имеет скоринг A+ для своего сервиса.

Для оценки сервисов, у нас используется сервис скоринга. Каждый сервис в зависимости от уязвимостей в пайплайне получает оценку от С до А+, где С означает, что все плохо, а А+ — все отлично и лучше, чем у других.

Оценка дается не просто так, а на основе политики ИБ. Скоринг суммирует критичности файндингов и ориентируется на порог срабатывания. При наличии высокой или критичной уязвимости присваивается оценка B или C, и политика ИБ запрещает релиз.

Так скоринг видят разработчики
Так скоринг видят разработчики

Скоринг — лишь часть мотивации, которая дает нам понять, что сервис работает и за ним наблюдают. У сервисов без поддержки оценка падает достаточно часто и быстро (спасибо свежим CVE-шкам).

Мотивация или строгие требования?

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

Security Quality Gate (далее SQG) — часть жесткой мотивации. Это гайки, что незаметно подкручиваются и не дают расслабиться командам разработки. Каждая уязвимость оценивается по критичности и накидывает вес в общую копилку. Чем больше вес — тем меньше вероятность, что сервис пустят в прод.

Как накидываются оценки для уязвимостей, исходя из инструмента, нашедшего потенциальную уязвимость:

SAST

  • Уязвимость высокого уровня критичности — 10 баллов

  • Уязвимость среднего уровня критичности — 5 баллов

  • Уязвимость низкого уровня критичности — 3 балла

Secrets

  • Любой найденный секрет — 10 баллов

SCA

  • Уязвимость высокого уровня критичности в библиотеке — 10 баллов

  • Уязвимость среднего уровня критичности в библиотеке — 5 баллов

  • Уязвимость низкого уровня критичности в библиотеке — 3 балла

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

Порог срабатывания можно тоже скорректировать. Но в целом мы выставляем 10 баллов для большинства проектов. При оценке 10 и выше пайплайн блокируется и заставляет разработчика обратить на себя внимание.

В период адаптации команд шаг SQG в пайплайне просто завершается как требующий внимания (Warning). Когда мы понимаем, что команда умеет жить с SQG и пишет исключения, мы можем включить SQG в блокирующем режиме. В этом случае, если джоба SQG упала, то и пайплайн тоже заблокируется.

Развиваем практики дальше

Основная цель на ближайшее время — включить Security Quality Gate на все проекты в компании. Это необходимо, чтобы исключить возможность релиза сервисов с найденными статическими анализаторами критичных уязвимостей.

Сами Security Quality Gate могут теперь включаться самостоятельно при выполнении определенных условий:

  1. Наличие оценок A/A+ в скоринге для всех типов сканирования.

  2. Наличие конфигурационного файла с исключениями в репозитории devsecops-configs. Данный файл может быть создан как самими разработчиками, так и AppSec BP. Конфигурационный файл может быть пустым. Создание конфиг-файла фактически означает, что первичные результаты сканирования были обработаны со стороны AppSec BP, а также — что репозиторий не является пустым.

  3. Наличие всей необходимой информации о сервисе в CMDB. Важные поля: указание ответственного AppSec BP и канала связи с командой разработки данного сервиса.

Как только команда рассмотрела все срабатывания сканеров, внесла исключения, заполнила информацию о проекте и команде в CMDB, они подписываются на выполнение политики ИБ с точки зрения релизов без уязвимостей.

Будет ли это мешать срочным релизам? Не должно. Все уязвимости должны рассматриваться при первом появлении. Если команда не обратила внимание и ей срочно надо идти в прод, то можно временно исключить все срабатывания, но ответственный AppSec BP возьмет эту команду в работу и проследит за процессом триажа и исправления найденных уязвимостей.

Зрелость команд по-новому

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

В интерфейсе платформы разработки теперь отображается оценка команды с точки зрения безопасности:

Команде следует самостоятельно следить за безопасностью и при необходимости приходить за аудитами и консультациями к AppSec BP.

А раньше мы просто просили читать наши регламенты и поддержку высокой оценки в скоринге считали за выдающийся результат :)

Что в итоге?

Мы сделали процесс разбора уязвимостей удобным для разработчиков и снизили рутинную загрузку AppSec-специалистов, освободив время на аудиты, ревью архитектуры, Bug Bounty и другие важные процессы. Оценивая команды с точки зрения зрелости процессов и подходов, у нас получилось начать мягкое масштабирование лучших практик.

Можно ли внедрить наш опыт во все компании? Сложно ответить на этот вопрос, поэтому буду рад обсудить потенциальные подводные камни с вами. Оставляйте комментарии!

Комментарии (0)