Опыт внедрения практик AppSec/DevSecOps

Процессы разработки должны быть построены так, чтобы гарантировать предсказуемый уровень безопасности продукта на выходе. Именно с такой идеей мы приступали к модернизации наших внутренних процессов в «ЛАНИТ ― Би Пи Эм».

Мы провели исследование мировых практик обеспечения безопасности, которые часто объединяют терминами AppSec (application security) и DevSecOps (development, security, and operations). Для нас было важно, что безопасность требуется не только при написании серверного кода. Фронт, инфраструктура, процессы сборки и развертывания также могут быть уязвимы. Поэтому мы обращали внимания на все эти аспекты. В этой и последующих статьях речь пойдет о наиболее интересных наших находках.

4a23b36be903262bbf8a1399852a501a.jpeg

Первый аспект ― проверка качества используемых зависимостей. Мы изучили популярные решения на рынке: Dependency-Track, Mend, Snyk, Black Duck, Sonatype Lifecycle, JFrog Xray. Каждый из этих инструментов предлагает набор функций для обнаружения уязвимостей, интеграцию с CI/CD, но большинство из них являются коммерческими. Мы выбрали Dependency-Track от OWASP. Это бесплатное open-source решение, которое покрывает все наши запросы.

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

91bebd42b26e586e7bd28118f3da79e6.jpeg

Кратко про принцип работы

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

  1. Сбор информации о зависимостях. Инструмент собирает данные обо всех используемых зависимостях проекта, включая frontend, backend и любые другие компоненты, где есть зависимости.

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

  3. Сканирование по базе уязвимостей. После сбора информации Dependency-Track проверяет все обнаруженные зависимости по базе данных уязвимостей, чтобы выявить потенциальные угрозы. Инструмент анализирует соответствие зависимостей известным уязвимостям, их критичность и влияние на проект.

Подключение к backend

Мы начали с backend на java. Встраивание в проект происходит достаточно просто. Существует maven-плагин для сбора информации о зависимостях в формате CycloneDX с хорошей документацией.

Подключение backend


    
        
            org.cyclonedx
            cyclonedx-maven-plugin
            ${cyclonedx-maven-plugin.version}
            
                
                    package
                    
                        makeAggregateBom
                    
                
            
        
    

В результате его работы создаются файлы в специальном формате SBOM со списком всех используемых в проекте зависимостей.

Далее этот файл должен попасть на сервер Dependency-Track, который разворачивается независимо и содержит красивый UI для визуализации. С его развертыванием у нас тоже не возникло проблем.

Подключение к frontend

Для фронта также имеется готовый плагин. Сборка и публикация зависимостей осуществляется в две команды. Суперпросто.

sh 'npx @cyclonedx/cyclonedx-npm --output-file bom.json --spec-version 1.5'
dependencyTrackPublisher artifact: 'bom.json', autoCreateProjects: true, projectName: 'project-name', projectVersion: "1", synchronous: true

Подключение к конвейеру

Мы хотели, чтобы при каждой сборке проекта информация о зависимостях собиралась и публиковалась на сервер, поэтому встроили этот шаг в CI/CD c помощью Jenkins-плагина.

Плагин легко интегрируется с Dependency-Track и имеет несколько удобных функций.

844aaeb42feff039a52e5340f45a90db.png

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

85560c5ebe34715875d2f91d155d454d.png

Еще один приятный момент ― можно отслеживать динамику по проекту. Тимлиды довольны.

Подводные камни

При внедрении в реальные проекты мы столкнулись с рядом нюансов, которые могут повлиять на эффективность и удобство работы с инструментом.

Локальная сборка

Для многих разработчиков критически важно обнаруживать уязвимые зависимости на самом раннем этапе, еще при локальной сборке, а не на конвейере CI/CD. Однако встроенного механизма для этого в Dependency-Track не нашлось.

Варианты решения

  1. Публикация локальной сборки на сервер и ручной анализ через UI. Можно загружать BOM (Bill of Materials) с локальной сборки в Dependency-Track и проверять уязвимости вручную через веб-интерфейс. Однако этот подход неудобен и трудоемок, особенно для частых проверок в процессе локальной разработки.

  2. Использование Dependency-Check. Это отдельная библиотека от OWASP, которая может быть встроена в процесс сборки. Она способна блокировать сборку при обнаружении уязвимых зависимостей. Можно настроить ее выполнение через Maven-профили, чтобы проверка запускалась только при локальных прогонах, не затрагивая CI/CD. Dependency-Check использует ту же базу данных уязвимостей, что и Dependency-Track, что делает этот вариант подходящим для раннего обнаружения проблем.

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

Мы решили пожертвовать возможностью локальной проверки зависимостей. Для нас главным было качество сборок на конвейере.

Доверие к базе уязвимостей

Основной источник информации об уязвимостях — база NVD (National Vulnerability Database), которая поддерживается Национальным институтом стандартов и технологий США (NIST). Использование этой базы данных, несмотря на ее авторитет и надежность, может нести определенные риски.

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

  • Что, если достоверность базы будет скомпрометирована? Возможные ошибки или манипуляции с данными могут снизить доверие к системе безопасности.

Однако Dependency-Track обладает возможностями, которые помогают минимизировать эти риски.

  • Локальная реплика базы уязвимостей. Dependency-Track создает свою копию базы данных и синхронизирует ее по мере возможности, что позволяет работать автономно без постоянного подключения к NVD. Это критично для обеспечения устойчивости процесса даже при потере связи с внешним источником. Также инструмент позволяет использовать зеркала вместо оригинальной базы.

  • Управление списком уязвимостей через UI. Интерфейс Dependency-Track позволяет вручную управлять списками уязвимостей, корректировать их, добавлять или исключать элементы по своему усмотрению. Это дает команде возможность гибко реагировать на изменяющиеся условия и поддерживать актуальность данных.

280ac10db19d97dd272595849d519022.png

Можно вручную расширять список уязвимых зависимостей. Либо воспользоваться готовым, составленным локальными компаниями. Например, есть база данных угроз ФСТЭК. 

Мы решили протестировать вышеупомянутую базу для расширения списка уязвимостей в Dependency-Track и столкнулись с рядом сложностей. Ниже основные выводы, которые мы сделали.

  • Несовместимость форматов. База ФСТЭК не поддерживает формат CVE, поэтому данные нужно вручную преобразовывать перед интеграцией с Dependency-Track. Это требует значительных временных затрат и создает дополнительную сложность при обновлении данных.

  • Пересечения с CVE. Часто записи из базы ФСТЭК ссылаются на уже существующие CVE, но сами по себе не являются полноценными уязвимостями для кода проекта. Это делает их более полезными для выявления уязвимых приложений и систем на рабочих станциях, а не для непосредственного анализа зависимостей в процессе разработки.

  • При желании запись из ФСТЭК можно вручную добавить в Dependency-Track. Несмотря на неудобства, связанные с преобразованием формата, записи из ФСТЭК можно перенести на локальный сервер Dependency-Track. Это позволяет расширить базу уязвимостей проекта, учитывая специфические угрозы, которые не охватываются международными источниками.

  • Если очень хочется, можно даже автоматизировать этот процесс и наполнять базу данных напрямую, минуя UI.

ac04c9ef3b876dd1cc2ecdf21050a0ba.png

Управление ложными срабатываниями

abd1b461db25418da061f7fce60b07c4.png

Dependency-Track не только позволяет добавлять новые уязвимости, но и предоставляет инструменты для управления ложными срабатываниями. Это особенно полезно при работе с большим объемом данных, когда некоторые уязвимости могут быть ошибочно помечены как критические.

  • Фильтрация и настройка исключений. С помощью интерфейса можно исключать ложные срабатывания, добавлять комментарии и обоснования, что позволяет держать список актуальных уязвимостей под контролем.

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

Разделение доступа по проектам

Еще один нюанс использования Dependency-Track ― возможность сокрытия результатов анализа проекта для других команд.

Для некоторых проектов крайне важно не распространять информацию об уязвимостях за пределы команды. Ранее в Dependency-Track не было возможность разделить доступ к результатам анализа. Однако в последних версиях такая возможность появилась в beta-режиме.

c09d35474410467b9dc27a8a25918217.png

Также имеется интеграция с LDAP/AD, а значит, можно использовать имеющийся в организации подход к авторизации. Поддерживается SSO с помощью OpenID. Однако аутентификация происходит не без участия пользователя. Вместо логина и пароля нужно нажать кнопку OpenID.

95795fb427032b05ba92b46f1071a722.png

Результаты пилотирования

Пилотное внедрение Dependency-Track показало, что использование уязвимых зависимостей — это распространенная проблема, с которой сталкиваются практически все проекты, особенно в условиях активного использования open-source библиотек. Без таких специализированных инструментов, как Dependency-Track, разработчики часто не осознают наличие этой проблемы, а уязвимости могут оставаться незамеченными на протяжении всего жизненного цикла продукта.

Интеграция Dependency-Track в процесс разработки прошла быстро и без особых трудностей. Инструмент легко встроился в существующие пайплайны и начал приносить результаты практически сразу после настройки. Команда получила своевременные уведомления о выявленных уязвимостях и устаревших версиях.

Помимо анализа уязвимостей, использование Dependency-Track дало дополнительное преимущество — возможность автоматического анализа лицензий, используемых библиотек и компонентов. Этот аспект также важен для наших проектов, так как позволяет следить за соответствием лицензий внутренним требованиям и снижать риски нарушения интеллектуальных прав. 

86eaec33946d7cc22fc87854dd802d09.png

Таким образом, внедрение Dependency-Track не только улучшило контроль безопасности зависимостей, но и позволило обеспечить всесторонний подход к управлению рисками, связанными с использованием стороннего кода и лицензий. Это абсолютный must have на каждом проекте, где вы задумываетесь о безопасности продукта.

© Habrahabr.ru