Как стать автором
Обновить
376.91
Ozon Tech
Стремимся делать лучший e-commerce в России

Проект RISK: как мы управляем уязвимостями эффективно

Время на прочтение12 мин
Количество просмотров5.3K

Мы серьёзно подходим к вопросам информационной безопасности наших продуктов: бережно относимся к пользовательским данным и разрабатываем сервисы с учётом требований информационной безопасности (ИБ) и публичных стандартов по разработке безопасных приложений. К сожалению, при этом всё равно могут встречаться уязвимости, создающие риски безопасности. Этого не нужно бояться, а лучше использовать эти знания для улучшения существующих контролей безопасности и построения новых. Для этого необходим видимый, эффективный и измеряемый процесс управления уязвимостями, который мы смогли построить в Ozon, и теперь хотим поделиться опытом, советами и граблями, на которые лучше не наступать. 

Какие варианты организации процесса рассматривали и что выбрали? 

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

  1. Унифицированного подхода к регистрации уязвимостей в наших сервисах. 

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

Нам очень нравится методология OWASP SAMM — мы используем её как фреймворк для построения жизненного цикла разработки безопасных приложений (S-SDLC):

OWASP SAMM v2. Бизнес-функции и практики ИБ, owaspsamm.org/about/
OWASP SAMM v2. Бизнес-функции и практики ИБ, owaspsamm.org/about/

Среди разных практик ИБ, сгруппированных по бизнес-доменам, есть то, что нам интересно, а именно раздел Defect Management

The Defect Management (DM) practice focuses on collecting, recording, and analyzing software security defects and enriching them with information to drive metrics-based decisions. 

То есть фактически тогда мы решили сделать первый уровень зрелости: 

Transparency of known security defects impacting particular applications 

В качестве багтрекера командами разработки в Ozon используется великая и могучая Джира. Исходя из этого, мы внедрили первую версию процесса, добавив в каждый проект в Джире отдельный тип тикета «Уязвимость». Приоритет тикета показывает «Уровень опасности». Таким образом получилось выделить исправление уязвимости на фоне просто задач по разработке и исправлению багов. 

В ходе первого года работы по такой схеме выяснилось, что: 

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

  2. Достаточно проблематично внедрить для определённого типа тикета («Уязвимость») единую схему ограничения доступа для всех проектов, коих у нас сотни. 

  3. Бывало, что и команда ИБ натыкалась на ограничения доступа при попытке заведения новых тикетов. 

  4. Не всегда сразу понятно, в каком проекте необходимо завести задачу по исправлению уязвимости, в то время как работа по ней уже ведётся и надо её где-то «приземлить». Например, для работы над исследованием потенциальной проблемы безопасности в рамках обработки репортов из нашей багбаунти-программы. 

  5. У нас для задач на разработку используется унифицированный общий процесс (workflow) для проектов, которые выкладывают свой код в продакшен (весьма удобно и, надеюсь, что мы расскажем об этом в будущих постах). Если кратко, то это обязательный набор статусов и переходов для тикетов в Джире, жёстко связанный с процессом CI/CD. Мы хотели иметь свой флоу в контексте исправления уязвимостей (в частности, убрать статус «Бэклог» и добавить специфичные статусы), и это могло стать проблемой.  

Исходя из этого, мы приняли решение о переформатировании процесса в проект RISK. Таким образом, у команды ИБ появлялось гораздо больше возможностей по организации своего флоу в тикетах, ограничению доступа и т. д. Для руководителей разработки такой подход более привычен и удобен. Более того, наш процесс достаточно сильно похож на аналогичный процесс управления инцидентами и уже знаком целевой аудитории, что упростило его внедрение. Кстати, об этом процессе уже рассказал мой коллега в статье «Как упавший продакшен делает нас лучше».  

Пример RISK-тикета
Пример RISK-тикета

Почему мы назвали проект RISK, а не, скажем, VULNS? На такой идентификатор нас натолкнул интересный доклад Дэниса Круза “Using JIRA to manage Risks and Security Champions activities” про принципы организации аналогичного процесса в Джире. В нём автор предлагает именно так назвать соответствующий проект. Получилось действительно лаконично и удобно в обращении: 

— А вы уже завели риск? 

— Вот же ж RISK-2702! 

Удачно совпало, что слово «риск» есть в русском языке, — и RISK-2702 читается и слышится всеми участниками процесса, включая представителей команд разработки, лучше, чем VULNS-2702 или VULN-2702

Помимо того, что RISK — это идентификатор проекта в Джире, есть и более объёмное толкование (на самом деле их несколько, но тут мы будем исходить из одного). Воспользуемся для этого документом OWASP Top Ten 2017: Application Security Risks, в котором наглядно показана схема риска безопасности: 

OWASP Top Ten 2017: Application Security Risks
OWASP Top Ten 2017: Application Security Risks

Злоумышленники разными способами могут атаковать сервис и нанести нам ущерб. Это несёт риски безопасности, которые могут (или не могут) быть достаточно серьёзными и требующими внимания. Иногда эти способы легко найти и эксплуатировать, иногда — очень сложно. Аналогичная ситуация с возможным ущербом: его может не быть совсем или он может дорого стоить бизнесу.  

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

Как внедряли?

Как уже упомянул выше, у нас был первый подход к процессу регистрации уязвимостей в виде отдельного типа тикета «Уязвимость» во всех проектах разработки. Мы в очередной раз обратились к разделу Defect Management из OWASP SAMM и наметили требования к будущему проекту и соответствующему процессу. Для перехода на RISK-и, мы сначала с помощью команды админов нашей Джиры завели соответствующий проект со специальным флоу и нужными нам полями. Нам было важно сохранить всю историю уязвимостей и пришлось мигрировать старые тикеты в новую схему — по сути, ретроспективно создавать RISK-и для уже закрытых уязвимостей). 

В процессе управления уязвимостями нельзя забывать о его видимости для всех заинтересованных участников (разработчиков, менеджеров, QA-инженеров и руководителей направлений). Мы согласовали SLA по срокам исправления и подготовили внутренний лендинг про RISK-и на портале команды ИБ (именно на него ведёт ссылка крупными буквами «Описание проекта RISK» на примере тикета выше), где постарались максимально подробно и доходчиво рассказать о проекте для целевой аудитории (мы предпочитаем использовать формат карточек для оформления подобных текстов).  

В Ozon проводится достаточно много внутренних митапов и регулярных больших встреч, включая All Hands — самую большую встречу для всех сотрудников. На ней мы и выступили с презентацией нашего проекта и таким образом постарались охватить максимальную аудиторию. У нас также есть свои каналы распространения информации, в частности внутренний канал #news-security, в котором мы делимся полезными ссылками и рассказываем про безопасность интересно и на человеческом языке. Впоследствии RISK-и начали уже сами распространять информацию о себе, как бы странно это ни звучало. По факту они стали очень важной точкой коммуникации между инженерами ИБ и командами сервисов. 

Разобравшись с запуском RISK-проекта и его видимостью, мы взялись за автоматизацию процессов вокруг него: 

  • RISK-тикет, как уже отмечалось выше, важная точка коммуникации инженеров ИБ с разработчиками, и необходимо, чтобы он был хорошо структурирован и понятен всем. Поэтому мы запустили бота, который стал присматривать за такими тикетами и ругаться, если что-то было плохо заполнено и ему не удалось это заполнить самому. 

  • Нам было нужно автоматизированное форсирование сроков закрытия уязвимостей, и мы подготовили ряд мини-процессов, о которых пойдёт речь дальше.  

Ну и наконец, какой же процесс без метрик и оценки его эффективности? В Defect Management этому посвящён второй поток "Metrics and Feedback". Мы в итоге разделили метрики на два класса: 

  1. Верхнеуровневые. Они показывают динамику появления, закрытия, сроков и т. п. RISK-ов по направлениям разработки. 

  2. Специфичные. Они фокусируют внимание пользователя на низкоуровневых показателях: типах уязвимостей, источниках информации (по сути, процессах ИБ), времени детекта и жизни уязвимости и т. д. 

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

Жизненный цикл RISK-а

Предположим, что нам пришёл очередной репорт в багбаунти-программу. Наш бот через API площадки багбаунти-программы (ранее это был HackerOne) узнаёт об этом и создаёт алерт в сервисе управления инцидентами Opsgenie. В последнем у нас настроены дежурства (с эскалацией и прочими плюшками).  Дежурный подхватывает репорт и делает первичный анализ, включая проверку присланной уязвимости. Если репорт выглядит правдоподобно и в нём достаточно информации, то он переводится в соответствующий статус. Инженер ИБ заводит тикет в проекте RISK и берёт его в работу: 

  1. Подробно описывает суть проблемы, включая общее описание уязвимости, шаги для демонстрации (повторения атаки), описание потенциальных негативных последствий. 

  2. Указывает соответствующий ИБ-процесс в поле "Security Activity" (в данном случае как "Bug Bounty Program") и дополнительно — ссылку на репорт HackerOne. В последнем также указывается ссылка на RISK — таким образом мы получаем двухстороннюю связь. Остальные значения "Security Activity" и других полей RISK-а будут описаны ниже. Если кратко, то это процесс ИБ, который стал источником информации об уязвимости. 

  3. При необходимости ограничивает доступ к тикету с помощью поля «Уровень доступа». 

  4. Выставляет "Severity" тикета на основе экспертного заключения об уровне риска (в данном случае — об уровне опасности уязвимости). Он может быть скорректирован после обсуждения с представителем команды разработки сервиса. 

  5. Выставляет тип "Weakness" на основе справочника Common Weakness Enumeration (CWE)

А вот таким запросом в Джире можно найти все обнаруженные опасные уязвимости, которые могут привести к XSS-атакам на сервис конкретного направления, присланные через багбаунти-программу: 

project = RISK AND Severity in (High, Critical) AND Weakness = 79 AND "Security activity" = "Bug Bounty Program" AND component = "Puschase and tools" 

После создания RISK-а в Slack-канал #risk-of-the-day прилетает уведомление об этом, чтобы все заинтересованные могли следить за новым и интересным :) 

Далее необходимо идентифицировать (микро)сервис, в котором была обнаружена уязвимость. Микросервисов у нас уже более 2800, так что это не всегда простая задача, для решения которой у нас есть отдельный алгоритм под названием «Поиск хозяев».  В конечном итоге, мы находим сервис-виновник, а через единый справочник сервисов — соответствующую команду разработки. Идентификатор сервиса прописывается в специальное (и весьма полезное) поле "Service Name". Для чего оно используется, узнаете ниже в разделе про форсирование SLA по срокам исправления. 

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

Редко, но бывает и такое, что риск можно не исправлять (да-да, утверждение может показаться немного странным на первый взгляд в контексте статьи про информационную безопасность): риск уже компенсирован другими контролями ИБ и/или потенциальный ущерб достаточно незначителен. Примерами могут служить уязвимости вида self-XSS без явного вектора атаки или вывод незначительной отладочной информации в сообщениях об ошибках. В этих случаях RISK переходит на этап согласования принятия и, если всё нормально, то закрывается как «Согласованный». 

Общая схема статусов и переходов RISK-тикета
Общая схема статусов и переходов RISK-тикета

Когда уязвимость исправлена (и закрыты прилинкованные тикеты в проекте), инженер ИБ всё проверяет и закрывает RISK-тикет как «Решённый».  

В фоне жизненного цикла RISK-а происходят весьма интересные события. 

— Присмотр за открытыми рисками. Тут инженер ИБ регулярно проходит по всем открытым RISK-ам, чтобы удостовериться, что они будут закрыты в срок:  

  • если требуется дополнительная информация от ИБ, то предоставляет её, 

  • если задача не взята в план работ, то договаривается об этом. У задачи должен быть срок исправления (“Due Date”), 

  • если в задаче долгое время не было активности, то призывает в неё ответственного за продукт или соответствующую компоненту, 

  • если работы по задаче закончены, то проверяет, исправлена ли уязвимость, и, если да, закрывает задачу. 

— Форсирование SLA по срокам исправления уязвимостей (расскажу ниже подробнее про этот важный процесс).

— Регулярные встречи команды ИБ с руководителями разработки для анализа тенденций по RISK-ам в их направлениях:

  • сколько было выявлено рисков за последний месяц? 

  • сколько исправлено? 

  • как быстро исправляются риски? 

  • и т. д. 

Структура RISK-а

Давайте подробнее рассмотрим поля RISK-тикета. Помимо базовых, в нём есть специфичные поля, на основе которых потом делается аналитика. 

Поле 

Назначение 

Security Activity 

Источник информации о проблеме безопасности: 

— Internal Security Audit (внутренний аудит безопасности силами команды ИБ), 

— External Security Audit (аудит силами внешнего подрядчика), 

— Bug Bounty Program (читайте нашу статью о запуске), 

— SAST (наши джобы по автоматизированному анализу безопасности кода), 

— DAST (сканирование сервисов на наличие уязвимости), 

— SCA (мониторинг уязвимостей в сторонних компонентах), 

— Threat Assessment (процесс моделирования угроз), 

— Secret Detection (поиск секретов в коде). 

Уровень доступа 

Возможность временного ограничения доступа к специфичным рискам. 

— Public: выставляется по умолчанию. Доступ имеют все аутентифицированные в Джире пользователи. 

— Private: доступ к тикету имеют представители команды ИБ и те, кто в него добавлен. 

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

Weakness 

Тип уязвимости, которая привела к риску. Используем список CWE List Version 4.4

Severity 

Уровень опасности: Low, Moderate, High, Critical. Возможно, в будущем мы перейдём на отдельный от уязвимости CVSS Risk Score. 

Сейчас уровень опасности конкретного риска определяется субъективно инженером ИБ совместно с ответственным и с учётом специфики сервиса. Максимальные сроки исправления рисков безопасности: 

— High и Critical: до двух недель, 

— Low и Moderate: до одного месяца. 

Components 

Направление, внутри которого находится соответствующая команда разработки сервиса. 

Found in Prod 

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

Потенциальный ущерб 

Описание потенциальных негативных последствий в случае реализации угрозы. 

Application Type 

Мы разделяем RISK-тикеты по типу приложения/сервиса, в котором была обнаружена уязвимость. Значения: 

— Frontend, 

— Backend, 

— Mobile. 

Service Name 

В качестве идентификатора сервиса используется значение имени сервиса (оно уникально и обязательно для всех сервисов в Ozon). 

Форсирование SLA по исправлению RISK-ов 

После того как риск безопасности подтвердился инженером ИБ и передан в работу, начинается отсчёт времени SLA исправления со стороны сервиса. Для того чтобы мы не выходили за пределы этих сроков используются следующие процессы: 

  1. Для критичного RISK-а мы заводим P1-инцидент​ (максимальный приоритет, см. статью «Как упавший продакшен делает нас лучше») — и время его починки исчисляется часами. Это очень мощный инструмент (эдакий BFG9000), который заставляет команду сервиса в буквальном смысле бросать всё и заниматься исправлением уязвимости. Нам приходилось применять его крайне редко, но хорошо иметь его в арсенале.

  2. Бот ИБ регулярно приходит в «забытые» тикеты и уведомляет ответственного о том, что близится к окончанию или уже исчерпан срок SLA.

  3. Проблемные тикеты эскалируются автоматизированно по следующему алгоритму:

    • при игнорировании тикета на протяжении трёх дней бот ИБ оповещает ответственного о наличии проблемы;

    • при очередном двухдневном игнорировании он подготавливает эскалацию до руководителя направления;

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

  4. В Ozon есть единый для всех сервисов CI/CD-пайплайн релиза и выкладки в прод, что очень удобно. В нём уже есть несколько контролей ИБ, включая «Шлюз безопасности». В рамках этого важного и сильного контроля на основе поля "Service Name" происходит поиск незакрытых просроченных RISK-ов для соответствующего сервиса. Если таковые есть и они не исправляются в рамках этого релиза, то он блокируется.

Итоги и планы

Собрав определённое количество граблей, мы внедрили эффективный и измеряемый процесс управления уязвимостями на базе единого RISK-реестра: 

  • Все уязвимости всех сервисов и приложений Ozon регистрируются в едином проекте RISK в виде тикетов, обогащаясь полезной информацией (уровень опасности, потенциальный ущерб, CWE, процесс ИБ, сервис и направление и т. д.). 

  • На сроки исправления рисков действует SLA (они различаются в зависимости от уровня опасности). Они форсируются различными контролями, включая «Шлюз безопасности» на этапе выкладки новых версий сервисов. 

  • У нас есть специализированный сервис агрегации метрик вокруг RISK-ов, и регулярный их анализ вместе с руководителями разработки. 

  • Ответственный за исправление риска — хозяин сервиса либо руководитель направления. Команда ИБ помогает в оценке риска и подтверждении его закрытия, а также форсирует SLA по закрытию и эскалирует RISK-ки при его нарушениях. 

Что мы хотим улучшить? Например, научиться считать и сделать отдельно дашборд с более специфичными метриками (Time-To-Detect, Window-of-Exposure с привязкой к процессу ИБ и т. д.) с их регулярным анализом. В итоге мы планируем прокачать наш процесс до максимального уровня в потоке "Metrics and Feedback" из OWASP SAMM: Defect Management. 

P. S. Если у вас ещё нет процесса управления уязвимостями?

Я бы порекомендовал следующее:

  1. Если у вас есть возможность, то сделайте в Джире проект RISK с минимальным набором специфичных полей. Начните с уровня опасности, описания ущерба и компонент по командам разработки. Регистрируйте там все новые уязвимости. 

  2. Расскажите всем разработчикам об этом процессе и задекларируйте SLA по исправлению. 

  3. Организуйте регулярный анализ найденных уязвимостей. 

Иными словами, попробуйте реализовать первый уровень зрелости из OWASP SAMM: Defect Management — и у вас появится базовое понимание масштаба проблем безопасности и что с этим можно сделать. 

Теги:
Хабы:
Всего голосов 17: ↑17 и ↓0+17
Комментарии2

Публикации

Информация

Сайт
ozon.tech
Дата регистрации
Дата основания
Численность
5 001–10 000 человек
Местоположение
Россия