Как упростить процесс исправления багов и не допустить уязвимый код в релиз? Использовать инструменты контроля качества. Для поиска ошибок и уязвимостей воспользуемся PVS-Studio, а для работы с отчётом — DefectDojo. В статье рассмотрим, как совместно использовать эти инструменты.
PVS‑Studio — это статический анализатор кода, предназначенный для поиска ошибок и потенциальных уязвимостей в C, С++, С# и Java проектах.
DefectDojo — это DevSecOps платформа, система отслеживания ошибок и уязвимостей. Она обладает функциями для работы с отчётами, включая возможность запоминания ложных срабатываний и удаления дубликатов. DefectDojo интегрируется с JIRA, умеет сохранять метрики и строить графики их изменения.
Используя новый формат отчёта PVS-Studio для DefectDojo, можно получить все преимущества платформы при работе с результатами анализа и управлении процессом устранения ошибок.
Инсталлятор PVS-Studio и триальный ключ можно получить здесь. Процесс установки в разном окружении описан в документации:
DefectDojo можно установить несколькими способами: например, используя Docker-образ, получить как SaaS или развернуть локально. Со всеми способами можно ознакомится на этой странице.
Посмотрим, как установить DefectDojo с помощью docker-compose.yml.
Для этого нам понадобится как минимум Docker версии 19.03.0 и Docker Compose 1.28.0.
Первым шагом нужно клонировать GitHub репозиторий DefectDojo:
git clone https://github.com/DefectDojo/django-DefectDojo.git
После этого нужно перейти в директорию django-DefectDojo и запустить сборку Docker-образов. Для запуска docker-compose нужно указать параметры '‑‑profile' и '‑‑env-file'.
В этом варианте я использую комбинацию PostgreSQL и RabbitMQ. Команда запуска docker-compose будет выглядеть следующим образом:
docker-compose --profile postgres-rabbitmq ^
--env-file .\docker\enviroment\postgres-rabbitmq.env up
После запуска контейнеров в DefectDojo можно зайти из учётной записи администратора. Чтобы получить пароль администратора, нужно использовать следующую команду:
docker-compose logs initializer | grep "Admin password:"
или
docker-compose logs initializer | find "Admin password:"
По умолчанию DefectDojo разворачивается на 8080 порте. Изменить его можно в файле docker-compose.yml.
Для правильной работы отчёта PVS-Studio в DefectDojo необходимо модифицировать файл 'local_settings.py'. В нашем варианте запуска этот файл должен располагаться в директории /docker/extra_settings/. В 'local_settings.py' нужно дописать строку:
HASHCODE_FIELDS_PER_SCANNER=
{"PVS-Studio Scan (Generic Findings Import)":["unique_id_from_tool"]}.
Благодаря этой настройке DefectDojo понимает, какое поле отчёта использовать для идентификации дубликатов сообщений.
Также в настройках DefectDojo необходимо включить настройку 'False positive history'. Она отвечает за то, чтобы информация о ложных срабатываниях сохранялась между отчётами.
Теперь, когда DefectDojo развернут, нужно подготовить его для работы с проектами и отчётами. В качестве тестового проекта будет использоваться открытый проект COVID-19 CovidSim Model, написанный на языке C++.
Сперва в DefectDojo нужно создать Product: 'Products'->'Add Product'.
После этого нужно заполнить информацию о проекте. Для теста я заполнил только обязательные поля и перенёс описание проекта из его GitHub-репозитория.
В созданный Product нужно добавить новый engagement. Это основная сущность, в которую будет загружаться отчёт анализатора и с которой мы будем работать.
В DefectDojo существует два вида engagement'ов: Interactive и CI/CD. Во второй можно дополнительно передавать информацию из CI/CD системы, например, номер сборки. На работу с отчётом этот выбор не влияет.
Стоит сказать, что существует несколько вариантов работы с результатами анализа. Один из них — создание нового engagement'а для каждого нового отчёта. В этом случае следует убедиться, что настройка 'Deduplication within this engagement only' выключена. Если она будет включена, то при загрузке нового отчёта пропадёт информация о уже размеченных предупреждениях.
В этом примере я загружаю все отчёты в один engagement. DefectDojo гибкий инструмент и позволяет настроить workflow под нужды пользователя.
Для автоматизации процесса проверки и загрузки отчёта в DefectDojo я сделал небольшую Jenkins задачу. Рассмотрим её подробнее.
Первым делом нужно доставить проект covid-sim и вспомогательный Python-скрипт на Jenkins. Для этого добавим в pipeline следующие шаги:
stage('Checkout'){
steps{
dir('defectdojo'){
checkout([
$class: 'GitSCM',
branches: [[name: 'main']],
userRemoteConfigs:
[[url: 'https://github.com/viva64/DefectDojo-QualityGate.git']]
])
}
dir('covid-sim'){
checkout([
$class: 'GitSCM',
branches: [[name: 'master']],
userRemoteConfigs: [[url: 'https://github.com/mrc-ide/covid-sim.git']]
])
}
}
}
Следующим этапом будет запуск проверки проекта. Добавим соответствующий шаг в скрипт:
stage('Analyze'){
steps{
dir('covid-sim'){
bat"""
PVS-Studio_Cmd.exe -t covid-sim.sln
IF %ERRORLEVEL% == 256 SET /A \"ERRORLEVEL=0\"
EXIT /B %ERRORLEVEL%
"""
}
}
}
Примечание. Запуск анализа может отличаться в зависимости от операционной системы и языка программирования анализируемого проекта. Вы можете обратиться к документации PVS‑Studio для получения инструкции по запуску анализа конкретно для вашего случая.
Код возврата 256 утилиты PVS-Studio_Cmd.exe означает, что в проекте обнаружены потенциальные ошибки. В результате этого шага будет создан отчёт 'covid-sim.plog' в директории проекта.
После того как отчёт получен, его необходимо преобразовать в специальный формат. Добавим шаг конвертации в наш pipeline:
stage('Convert'){
steps{
dir('covid-sim'){
bat """
PlogConverter.exe -t DefectDojo -a GA:1,2,3 covid-sim.plog
"""
}
}
}
В этой команде применяются следующие параметры:
Формат DefectDojo доступен в PlogConverter, идущем с PVS-Studio версии 7.26. Вы можете узнать больше об утилите конвертации в документации.
В результате этого шага будет создан отчёт 'covid-sim.plog.defectdojo.json'. Его-то и нужно загрузить в DefectDojo. Для этого добавим следующий шаг в pipeline:
stage('Upload report'){
steps{
dir('covid-sim'){
bat"""
curl -X POST ^
-H Authorization:"Token 44ac826dc4f3b6add1161dab11b49402618efaba" ^
-F scan_type="Generic Findings Import" ^
-F file=@covid-sim.plog.defectdojo.json ^
-F engagement=6 ^
-H Content-Type:multipart/form-data ^
-H accept:application/json ^
http://localhost:8080/api/v2/import-scan/
"""
}
}
}
В параметре 'file' нужно указать путь до отчёта, а в 'engagement' — номер того engagement'а, в который будет загружен отчёт.
Токен для этой команды можно получить на странице API v2 Key.
После выполнения предыдущего шага отчёт должен появиться в указанном engagement.
Последний загруженный отчёт будет первым в списке (если в engagement нет отчётов другого типа). При клике на него откроется таблица с предупреждениями анализатора.
DefectDojo позволяет фильтровать сообщения по разным категориям, включая уровень достоверности, номер CWE, статус, и т.д.
При нажатии на поле 'Name' откроется описание предупреждения.
Здесь можно найти подробное описание ошибки и её расположение.
После загрузки отчёта все сообщения будут иметь статус 'Inactive'. При начале работы с предупреждением поменяйте его статус на 'Active'. Тогда это сообщение можно будет найти на вкладке 'Findings'.
После проверки предупреждения отметьте его либо как 'Verified' и 'Mitigated', если вы исправили ошибку, либо как 'False Positive', если предупреждение оказалось ложным.
Отметим несколько предупреждений как ложные. На странице с описанием engagement отобразится статистика по тесту.
DefectDojo — гибкий инструмент, который можно настроить в соответствии с вашими потребностями. Это позволяет встроить его в пользовательские процессы. DefectDojo имеет API для автоматизации и настройки работы в нём. Посмотрим, как с помощью API можно реализовать такой механизм, как Quality Gate.
Quality Gate — это индикатор соответствия кода проекта заданным пороговым значениям метрик. Качество кода и его безопасность неразрывно связаны. Quality Gate мешает внедрению кода, не соответствующего стандартам.
Для реализации Quality Gate я написал небольшой python-скрипт. Найти и скачать его можно здесь. Скрипт получает последний загруженный отчёт из предоставленного engagement, определяет количество предупреждений по уровням достоверности и сравнивает его с эталонным значением.
Для автоматизации проверки Quality Gate добавим новый шаг в Jenkins pipeline.
stage('Quality Gate'){
steps{
dir('defectdojo'){
sleep(time:10,unit:"SECONDS")
bat """
python ./qualitygate.py --engagement 1 ^
--critical 0 --high 10 ^
--medium 50 --low 250
"""
}
}
}
Из приведенного выше примера следует, что шаг pipeline закончится провалом, если в отчёте будет хотя бы одно Critical предупреждение или больше 10 High, 50 Medium, 250 Low предупреждений.
Задержка перед выполнением скрипта нужна потому, что на прошлом шаге мы загрузили отчёт, а серверу DefectDojo нужно время, чтобы обработать его.
Также для работы скрипта нужно определить переменные окружения DD_HOST и DD_API_TOKEN. Для этого нужно добавить блок environment в pipeline.
environment {
DD_HOST = 'http://localhost:8080/'
DD_API_TOKEN='44ac826dc4f3b6add1161dab11b49402618efaba'
}
Как мы увидели, настроить работу с отчётом PVS-Studio в DefectDojo довольно просто. В результате мы получаем возможность удобно работать с предупреждениями анализатора и контролировать их исправление.
Для тех, кто заинтересовался совместным использованием этих продуктов: по этой ссылке вы можете скачать анализатор, а здесь узнать больше о DefectDojo.