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

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

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

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

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

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

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

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

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

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

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

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

<build>
    <plugins>
        <plugin>
            <groupId>org.cyclonedx</groupId>
            <artifactId>cyclonedx-maven-plugin</artifactId>
            <version>${cyclonedx-maven-plugin.version}</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>makeAggregateBom</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

В результате его работы создаются файлы в специальном формате 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 и имеет несколько удобных функций.

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

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

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

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

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

Для многих разработчиков критически важно обнаруживать уязвимые зависимости на самом раннем этапе, еще при локальной сборке, а не на конвейере 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 позволяет вручную управлять списками уязвимостей, корректировать их, добавлять или исключать элементы по своему усмотрению. Это дает команде возможность гибко реагировать на изменяющиеся условия и поддерживать актуальность данных.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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