Количество киберинцидентов постоянно увеличивается, что вынуждает компании реагировать на растущие риски и делает практику DevSecOps обязательной для соблюдения при разработке ИТ-продуктов. При этом топорное внедрение мер не просто не гарантирует безопасность разработки, а может вызвать обратный эффект.
Разбираемся, что и когда нужно делать, чтобы разработка была безопасной.
Материал подготовлен по мотивам вебинара «DevSecOps: организация безопасной разработки на уровне процессов».
DevOps vs DevSecOps
DevOps — методология разработки ПО, которая объединяет разработку (Development) и операции (Operations) для выстраивания более эффективного и быстрого процесса разработки и доставки приложений. Основная цель DevOps — наладить непрерывную связь между разработчиками, тестировщиками и администраторами, чтобы сделать жизненный цикл продукта непрерывным.
DevSecOps можно рассматривать в качестве апдейта методологии DevOps: подход подразумевает не расширение классического пайплайна DevOps, а только интеграцию в него методов безопасности. При этом, согласно DevSecOps, к циклу разработки подключаются специалисты по информационной безопасности, которые гарантируют, что:
- реализуемые решения не противоречат требованиям ИБ и регламентам компании;
- в конфигурации нет уязвимых мест;
- все компоненты системы имеют актуальные патчи, корректно настроены;
- разработана эксплуатационная документация в контексте ИБ.
Согласно практике DevSecOps, о безопасности разработки нужно начинать думать еще на этапе планирования будущего продукта. В противном случае может возникнуть ситуация, когда, например, код написан идеально, но в техническом дизайне не исключена возможность пользователей назначать себе привилегированные права, что полностью нивелирует любые дальнейшие меры безопасности.
Различия между жизненными циклами DevOps и DevSecOps
Следование методологии DevSecOps дает разработчикам и бизнесу ряд преимуществ.
- Повышение безопасности приложений. Практика DevSecOps гласит, что безопасность должна обеспечиваться и соблюдаться на каждом этапе жизненного цикла продукта. В результате проект получает эшелонированную глубокую защиту от любых возможных угроз информационной безопасности.
- Сокращение Time-to-market. Обычно продукт проверяется на соответствие ИБ ближе к релизу. Соответственно, при обнаружении любых проблем разработчики вынуждены откатываться к этапу с уязвимостями, устранять их и повторно проверять проект. Это не только сложно и дорого, но и долго, что влияет на сроки релиза продукта. С DevSecOps большинство ошибок удается уловить в момент их появления, что уменьшает время на устранение багов и сокращает Time-to-market.
- Улучшение качества продуктов. Концепция DevSecOps подразумевает глубокую проработку всех деталей проекта — сценариев пользовательских действий, нужных функций, вариантов реагирования на уязвимости и не только. Это несколько усложняет проектирование и разработку продукта, но позволяет создать решение, которое больше удовлетворяет запросы пользователей.
- Внедрение культуры безопасности. Раньше разработчики были ориентированы на быстрый релиз проектов или оперативное закрытие задач в зоне своей ответственности. Заботы о безопасности, как правило, отдавались на откуп тестировщикам и специалистам по ИБ. С внедрением DevSecOps появляется коллективная и персональная ответственность: любая допущенная ошибка сразу вернется на доработку.
- Выстраивание коммуникации и унификация подходов. Тесное взаимодействие разработчиков, тестировщиков, администраторов и безопасников означает унификацию используемых инструментов и методов. Это помогает уйти от «зоопарка технологий» и упрощает онбординг.
Гайдлайн по DevSecOps
Есть несколько подходов и рекомендаций, определяющих нормы внедрения DevSecOps-принципов в процесс разработки. Одним из базовых фолиантов в этом контексте является DevSecOps Guideline от OWASP — формируемое сообществом руководство, которое поясняет, как правильно выстроить процесс безопасной разработки и выявлять любые проблемы на ранних стадиях их возникновения.
Основная цель правил, описанных в DevSecOps Guideline, — обеспечить безопасность:
- кода (Custom Code Security),
- цепочки поставок (Supply Chain Security),
- среды исполнения (Runtime Protection).
При этом на каждой стадии нужны свои меры и подходы. Таких стадий семь:
- Init (стадия инициализации),
- Pre-commit,
- Commit-CI,
- Сontinuous-Delivery-CD,
- Deploy-CD-Colive,
- Operation,
- Governance (стадия управления).
Разберем подробнее каждую из них.
Стадия инициализации (Init)
Инициализация — этап, на котором еще нет кода, а есть только идея будущего продукта.
По рекомендациям DevSecOps Guideline, на этой стадии важно:
- привить культуру безопасной разработки внутри команд;
- выделить Security Champion внутри каждой из команд, то есть сотрудников команды разработки, выступающих в интересах группы ИБ.
При этом важно понимать следующее.
- Культуру безопасной разработки нельзя насаждать и навязывать. Если специалист не понимает ценности нововведений, любая инициатива может быть задвинута в дальний ящик и саботирована. Оптимально, чтобы приход к DevSecOps был эволюционным, а не революционным. Также важно, чтобы идея культуры безопасности пронизывала все структуры компании, а инициатором ее внедрения было руководство.
- Обычно на роль Security Champion назначают специалиста из команды. Но важно, чтобы человек на этой роли был независим и непредвзят — например, чтобы не замалчивал о возможных рисках под давлением начальства. Поэтому в качестве Security Champion нередко выступает тимлид, а иногда и вовсе специалисты из отдела информационной безопасности, тестировщики или аудиторы. Также важно, чтобы в команде был не один Security Champion: это повышает Bus factor и зависимость от одного специалиста, чего лучше не допускать.
Стадия Pre-commit
Основная задача на этапе Pre-commit — проверить безопасность на стадии, когда код написан, но еще не попал в систему контроля версий.
DevSecOps Guideline предписывает, что для этого нужны комплексные меры.
- Разработать модели угроз. Нужно определить, как будет работать приложение, в каких контурах, с какими правами доступа и принципами взаимодействия с другими компонентами. Важно выделить все потенциальные риски, предусмотреть защиту от них и разработать алгоритм действий на случай их реализации.
- Проверка кода на наличие секретов. Важно, чтобы в репозиторий вместе с исходным кодом не попали секретные данные: пароли, токены доступа, идентификационные данные, описание особенностей реализации и другие. Проверку на наличие секретов можно проводить как вручную, так и с помощью инструментов. Лучше в комплексе.
- Безопасное конфигурирование репозитория. Репозиторий должен быть настоящим сейфом. Для этого следует фильтровать файлы на запись, ограничивать права на доступ (в том числе на запись) к хранилищу по принципу наименьших привилегий, мониторить и фиксировать все обращения к репозиторию.
- Использование линтеров. Работа с линтерами — возможность статически проверить код на наличие подозрительных элементов, сложного синтаксиса, структурных ошибок, стилевых нарушений, «необычных» паттернов объявления функций и других проблем. С их помощью можно на ранних стадиях найти и закрыть дыры в коде, которыми могут воспользоваться злоумышленники.
Стадия Commit
Коммит — этап, когда код выкатывается в паблик и становится доступным для других пользователей (даже если репозиторий закрыт и доступ к коду есть у ограниченного количества людей). Фактически на этой стадии код впервые «светится» вовне и может стать целью злоумышленников, поэтому меры на этапе коммита должны быть соответствующими.
Здесь важно:
- Проводить статический анализ кода (SAST). Метод помогает находить ошибки в коде, которые могут привести к проблемам безопасности, без необходимости запуска приложения. SAST работает по принципу линтера, но с другим функционалом. Применение метода уменьшает вероятность попадания уязвимостей в продакшен.
- Выполнять анализ уязвимостей (SCA). Подразумевает поиск уязвимостей в сторонних компонентах, используемых в приложении.
- Безопасно конфигурировать образы контейнеров. Современные подходы к безопасности подразумевают выстраивание эшелонированной обороны с независимыми средствами на каждом уровне. Безопасная конфигурация образов — один из уровней выстраивания безопасности приложений. Оптимально использовать Distroless-образы, которые состоят из минимального количества исполняемых файлов и библиотек, необходимых для запуска. В Distroless-образах нет полноценных пакетов со всеми файлами, присутствующими в обычной системе, что уменьшает поверхность атаки и количество потенциальных мест входа для злоумышленников. Более того, если образ будет без «обвеса», даже в случае взлома злоумышленнику будет сложно разобраться, как с ним работать.
- Сканировать артефакты IaC. В концепции IaC именно код определяет параметры инфраструктуры, ее безопасность, целостность и надежность. Чтобы исключить все риски, надо сканировать артефакты IaC (например, скрипты Terraform) на наличие несанкционированных привилегированных эскалаций, дрифтинга конфигураций, ошибок и неверного синтаксиса, несоблюдения нормативных требований и другие проблемы.
- Проводить интерактивный анализ (IAST). IAST — гибридный механизм проверки, в котором комбинируются преимущества SAST и DAST. IAST позволяет динамически проверить приложение методом «серого ящика» (реализация приложения частично или полностью неизвестна), имитируя внешние атаки через разные уязвимости.
Стадия Continuous Delivery
По мнению специалистов OWASP и комьюнити, на этапе Continuous Delivery главными практиками обеспечения безопасности разработки являются:
- динамический анализ (DAST, Dynamic Application Security Testing) — проверка с имитацией внешних атак на разные векторы защиты;
- обеспечение безопасности API;
- проверка на наличие Misconfiguration (некорректной конфигурации).
Здесь стоит отметить, что обеспечение безопасности API в контексте стадии Continuous Delivery, до деплоя, нацелено именно на построение безопасной конфигурации API. То есть на этом этапе нужно предусмотреть и спроектировать:
- механизмы подключения;
- системы проверки прав доступа, сертификатов и токенов;
- изолированность подключений, в том числе DMZ, чтобы даже после взлома API злоумышленник не смог проникнуть во внутреннюю сеть;
- механизмы фильтрации запросов (например, по IP).
Такую подготовку важно проводить именно на этапе Continuous Delivery, чтобы проблемы уязвимости и незащищенности API не стали всплывать на стадиях, когда фикс таких проблем будет стоить дороже.
В контексте оценки Misconfiguration задачи сводятся к проверке конфигурационных файлов и контейнеров на целостность, отладку, ответствие рисков, что в деплой попадет «что-то лишнее» — например, грязный реестр, устаревший контейнер или вообще случайный файл. Игнорировать этот этап не стоит — можно надеяться, что успешный деплой подтвердит отсутствие ошибок, но даже успешный запуск не гарантирует, что проблемы не дадут о себе знать впоследствии.
Стадия Deploy-CD
От стадии к стадии уровень разработки и используемые практики трансформируются. Соответствующим образом трансформируются и меры организации безопасной разработки. Так, на стадии деплоя первоочередным становится решение двух глобальных массивов задач.
- Организовать надежное хранение ключей и сертификатов. Любая утечка этих файлов и данных повышает риск взлома системы и других серьезных последствий. Чтобы хранение было безопасным, важно использовать надежное хранилище, строго регламентировать порядок взаимодействия с этими данными, разграничивать права доступа к ним. Хранить ключи и сертификаты вместе с конфигурационными файлами как в закрытой, так и в «открытой» части сети не стоит.
- Обеспечить безопасность приложения с точки зрения Cloud-Native-подхода. Согласно методологии Cloud Native, важно обеспечить безопасность на всех уровнях инфраструктуры, включая сеть, хранилище данных, контейнеры и микросервисы. По DevSecOps Guideline от OWASP к обязательным мерам защиты на этапе Deploy-CD относится также выстраивание процессов и подключение инструментов для автоматического мониторинга, обнаружения уязвимостей и атак, а также их устранения. Наряду с этим важно использовать Cloud Native Application Protection Platform (CNAPP) — комплексное решение, сочетающее инструменты для защиты серверных рабочих нагрузок, а также выявления проблем неправильной конфигурации облака и рисков несоответствия нормативным требованиям.
Стадия Runtime
Даже деплой приложения и его вывод в Runtime не означает прекращение работы по созданию условий для безопасной разработки на уровне процессов. Более того, на этой стадии, когда потенциальных угроз становится больше (например, начинается работа с критическими и пользовательскими данными), количество необходимых мер тоже увеличивается.
Так, согласно DevSecOps Guideline к моменту запуска приложения надо:
- внедрить практику анализа уязвимостей инфраструктуры (анализ инфраструктуры облака, анализ контейнеров в Runtime) и предусмотреть порядок действий на случай обнаружения аномалий (например, заменять контейнеры, отправлять их в карантин или вообще удалять);
- внедрить процессы тестирования на проникновение (Black box, Grey box, White box), в том числе с привлечением внешних команд и использованием автоматизированных инструментов;
- провести тестирование методом Breach and Attack Simulation — подход позволяет непрерывно моделировать кибератаки для проверки кибербезопасности без влияния на системы в проде;
- подключиться к BugBounty — программа дает возможность привлекать сторонних специалистов к тестированию продукта и поиску уязвимостей и, как результат, получать оперативную обратную связь и сокращать время реагирования на возможные проблемы безопасности. Но подключаться к BugBounty стоит только при полной уверенности в безопасности приложения — в противном случае рисков от участия в программе будет больше, чем профита;
- сконфигурировать процессы логирования и мониторинга.
Стоит понимать, что выстраивание такой эшелонированной обороны, которая нужна на стадии Runtime, требует от компании определенного уровня зрелости с точки зрения безопасности и значительного запаса ресурсов — как финансов, так и времени специалистов.
Стадия управления (Governance)
В условиях идеального мира к этапу эксплуатации приложение приходит с полностью проработанной, настроенной и автоматизированной (в части использования инструментов) системой безопасности. То есть все меры и подходы, описанные ранее, должны быть внедрены, приняты и корректно работать.
На стадии Governance фактически добавляются практики, больше относящиеся к процессному управлению. Например, согласно DevSecOps Guideline, на стадии управления надо:
- выполнять аудит соответствия требованиям по безопасности;
- внедрять централизованное управление уязвимостями;
- использовать инструменты Policy-as-code;
- проводить анализ зрелости (Security Maturity);
- внедрить процессы Security Benchmarking.
Фактически внедрение этих мер замыкает цикл обеспечения безопасности и делает весь путь разработки понятным и прозрачным, а продукт — устойчивым к потенциальным угрозам.
Вывод
Создание условий для разработки безопасных приложений — непрерывный процесс, который не останавливается даже после выкатки в прод и требует постоянного вовлечения как разработчиков, так и других ИТ-специалистов. Более того, чем выше стадия готовности продукта, тем больше усилий нужно прикладывать для его защиты от внутренних и внешних угроз, а также технических сбоев — меры должны быть соразмерны увеличению рисков.
При этом главным условием, определяющим успешность всех усилий, является понимание значимости безопасной разработки на всех уровнях — от руководителя до специалистов на местах. Без внедрения культуры безопасной разработки любые затраты и усилия не принесут ожидаемых результатов.