Практические аспекты построения процесса безопасной разработки программного обеспечения
Игорь Беляков, 14/06/20
Наличие слабых мест в исходном коде программного обеспечения ухудшает его работу и провоцирует возникновение рисков, связанных с нарушением целостности и конфиденциальности информации. Чем грозит эксплуатация таких уязвимостей и можно ли сделать разработку приложения безопасной?
Игорь Беляков
CISO kupibilet.ru, к.т.н.
Реализация рисков на этапе эксплуатации может привести к серьезному финансовому и репутационному ущербу. Финансовый ущерб, как правило, включает в себя затраты на устранение уязвимости и выпуск новой версии программы, а также упущенную выгоду, которая может стать следствием снижения интереса клиентов к небезопасному приложению. Безопасная разработка программного обеспечения (Secure Software Development Lifecycle – SSDL) представляет собой подход, нацеленный на своевременное выявление и устранение уязвимостей в исходном коде. Построение SSDL силами разработчика программного обеспечения является наиболее верным решением, ведь именно разработчик заинтересован в снижении накладных расходов на поддержание продукта.
Стоимость устранения уязвимости на этапе разработки, как правило, сводится к затратам разработчика на проведение аналитики, выполнение необходимых изменений в исходном коде и проведение повторной проверки. Если же уязвимость была выявлена на этапе промышленной эксплуатации, то к указанным ранее затратам могут добавиться:
- расходы на выявление уязвимости (все сводится либо к оплате в рамках программы Bug Bounty, либо к оплате работы исследователя, выявившего уязвимость);
- расходы на обработку обращений клиентов (ставших следствием публикации информации об уязвимости или нарушением в работе программы);
- расходы на проведение анализа влияния уязвимости на участки кода, измененные после ее появления;
- а также расходы на сборку и вывод в промышленную эксплуатацию новой версии программы.
Учитывая, что выявление критической уязвимости вносит существенные коррективы в расстановку приоритетов по доработке, сроки вывода нового функционала в промышленную эксплуатацию могут существенно измениться.
Стоит отметить, что внедрение SSDL является обязательным при разработке приложений, осуществляющих обработку банковских карт и пр.
В сложившейся практике внедрение SSDL сводится к включению средства статического анализа исходного кода (Static Application Security Testing – SAST) в процесс тестирования приложения. Как правило, тестирование безопасности приложения осуществляется одновременно с функциональным тестированием (Quality Assurance – QA). То есть если приложение успешно проходит все проверки, его можно отправлять в промышленную эксплуатацию.
При построении процесса непрерывной безопасной разработки обязательно используются три основных компонента:
- GIT – распределенная система управления версиями, хранения и версионирования исходного кода.
- CI (Continuous Integration – непрерывная интеграция) – основная логика распространения новых версий программного обеспечения. Непрерывная интеграция – это практика разработки программного обеспечения, которая заключается в постоянном слиянии рабочих копий в общую основную ветвь разработки (до нескольких раз в день) и выполнении частых автоматизированных сборок проекта для скорейшего выявления потенциальных дефектов и решения интеграционных проблем.
- SAST – средство статического анализа исходного кода. Основной инструмент для поиска уязвимостей.
Существуют риски, связанные с уязвимостями, появившимися на этапе разработки программного обеспечения, и проведение статического анализа исходного кода приложения позволяет сравнительно быстро их выявить. Рассмотрим, какие недостатки исходного кода встречаются и к чему приводит их упущение:
- Нарушение синтаксиса языка. Чаще всего такие уязвимости вызывают нарушение работы приложения.
- Использование уязвимых функций или библиотек. В последнее время достаточно часто появлялась информация о внедрении вредоносного кода в Open Source, библиотеки или иные расширения. Так как многие коммерческие продукты используют сторонние библиотеки без дополнительной проверки, уязвимость библиотеки становится уязвимостью приложения.
- Хранение отладочных данных в исходном коде. Часто случаются ситуации, когда в исходном коде приложения записаны логины и пароли, используемые для отладки или тестирования. Получив доступ к исходному коду, злоумышленник может получить доступ и к приложению.
- Ошибки конфигурации приложения. Чаще всего сводятся к некорректной настройке используемых протоколов, а также внешних модулей и иных систем, включая базы данных. Такие ошибки позволяют получить несанкционированный доступ к информации.
- Обработка данных, полученных без предварительной проверки. Чаще всего источником таких данных является пользователь, который может ввести различные сомнительные сведения в приложение. Отсутствие проверки позволяет загрузить даже вредоносное программное обеспечение.
- Неиспользуемые участки кода, которые могут содержать логические бомбы или бэкдоры. В рамках сложных атак неиспользуемые участки кода могут быть незаметно изменены злоумышленником и использованы для манипуляции приложением.
Как создать безопасное ПО?
Чтобы не допустить присутствие уязвимостей в исходном коде, во время разработки приложения нужно соблюдать несколько условий и придерживаться следующих этапов:
- Разработка. На данном этапе создается новый функционал, проверяется корректность его работы и сохраняется в основной проект (Сommit) в GIT. Хорошим тоном считается регулярное создание резервных копий репозитория, что позволяет снизить риск утраты важного актива.
- Сборка. После накопления необходимого количества изменений по решению руководителя проекта в CI осуществляется сборка нового релиза проекта.
- Контроль. На данном этапе собранный релиз отправляется на функциональное тестирование и проверку безопасности. Все испытания должны обязательно выполняться в тестовой среде и с использованием тестовых данных. По результатам испытаний формируется заключение о возможности промышленной эксплуатации новой версии программы.
- Промышленная эксплуатация. Если проект успешно прошел все проверки, тогда он передается в промышленную эксплуатацию, т.е. выпускается новая версия программы. В свою очередь, сборка и внедрение новой версии программы обеспечивается системами CI/CD (Сontinuous Integration/Either Continuous Delivery or Continuous Deployment). Наиболее распространенные системы данного класса обладают всем необходимым функционалом для обеспечения хранения исходного кода, сборки новых версий, запуска задач тестирования и внедрения новых версий программы.
Роль SAST в создании безопасного приложения
Существует два основных варианта интеграции статического анализа кода (SAST) в процесс разработки:
- Наиболее правильным является выполнение статического анализа сразу после сборки релиза приложения. В данном случае CI передает собранный релиз на функциональное тестирование и на проверку безопасности. Если в приложении не выявлены функциональные нарушения или уязвимости, CI осуществляет выпуск приложения в промышленную эксплуатацию.
- Если процесс непрерывной разработки уже выстроен и функционирует исправно, то есть смысл в реализации параллельной проверки исходного кода. При таком подходе сканер исходного кода осуществляет регулярную проверку репозитория приложения (как правило, ветки Мaster) на наличие уязвимостей. Чаще всего сканирование осуществляется по рабочим дням в часы наименьшей нагрузки, как правило ночью. Отчет о результатах такого исследования направляется ответственным сотрудникам, которые могут принять решение о необходимости оперативного устранения уязвимости.
При проведении проверки возможен как полный, так и инкрементальный анализ кода. Выполнение полного анализа предполагает ревизию всего исходного кода программы, в то время как при инкрементальном анализе поиск уязвимостей осуществляется только в измененных участках кода. Полный анализ исходного кода обычно выполняется за несколько часов, в то время как инкрементальный занимает не более часа.
Необходимо отметить, что средства SAST могут быть встроены в инструментарий разработчика. Однако важным преимуществом использования отдельного сервиса для проверки безопасности исходного кода является возможность централизованного и независимого от разработчиков контроля отсутствия уязвимостей в нем.
Средства контроля исходного кода, встроенные в инструменты разработки, хоть и позволяют решить задачу проверки на отсутствие уязвимостей, но при этом обладают существенными недостатками:
- невозможно провести сопоставление выполненной проверки с конкретными релизами программы в GIT;
- при большом количестве разработчиков нет возможности осуществить оперативный контроль, чтобы отследить, проверялся ли исходный код и каков был результат.
Тестирование при разработке безопасного ПО
При построении безопасного программного обеспечения обязательным условием является выделение тестовой среды и среды разработки. Среда разработки используется для создания нового функционала. В тестовой среде необходимо осуществлять функциональное тестирование, а в "боевой среде" должно работать приложение. При этом необходимо выполнять следующие требования:
- Запрещается использовать одни и те же данные в процессах разработки, тестирования и эксплуатации. При нарушении этого требования возможны риски несанкционированного доступа к "боевому приложению" через тестовые учетные записи, а также риск разглашения конфиденциальной информации, используемой для тестирования.
- Необходимо обеспечить техническую идентичность всех сред функционирования приложения для обеспечения релевантности результатов.
- Необходимо обеспечить версионированность приложения для четкой идентификации результатов разработки и тестирования.
Использование нескольких распространенных статических анализаторов исходного кода показало практически полную идентичность в получаемых данных об уязвимостях. Следовательно, при выборе системы для статического анализа можно ориентироваться прежде всего на стоимость владения и возможность встраивания в текущие процессы.
В заключение необходимо отметить, что построение процесса безопасной разработки в долгосрочной перспективе окажет положительное влияние на качество разрабатываемого приложения и снизит стоимость его поддержки. При этом в условиях отсутствия принципиальной разницы между используемыми инструментами и подходе к сканированию при построении SSDL необходимо ориентироваться на существующие процессы разработки кода и компетенции сотрудников.