﻿# DefectDojo и PVS\-Studio: отслеживаем ошибки и уязвимости

Как упростить процесс исправления багов и не допустить уязвимый код в релиз? Использовать инструменты контроля качества\. Для поиска ошибок и уязвимостей воспользуемся PVS\-Studio, а для работы с отчётом — DefectDojo\. В статье рассмотрим, как совместно использовать эти инструменты\.

![1062_Integrating_PVS-Studio_with_DefectDojo_ru/image1.png](https://import.viva64.com/docx/blog/1062_Integrating_PVS-Studio_with_DefectDojo_ru/image1.png)

[PVS\-Studio](https://pvs-studio.ru/ru/) — это статический анализатор кода, предназначенный для поиска ошибок и потенциальных уязвимостей в  C, С\+\+, С\# и Java проектах\. 

[DefectDojo](https://github.com/DefectDojo/django-DefectDojo) — это DevSecOps платформа, система отслеживания ошибок и уязвимостей\. Она обладает функциями для работы с отчётами, включая возможность запоминания ложных срабатываний и удаления дубликатов\. DefectDojo интегрируется с JIRA, умеет сохранять метрики и строить графики их изменения\. 

Используя новый формат отчёта PVS\-Studio для DefectDojo, можно получить все преимущества платформы при работе с результатами анализа и управлении процессом устранения ошибок\.

## Установка PVS\-Studio и DefectDojo

### Установка анализатора PVS\-Studio

Инсталлятор PVS\-Studio и триальный ключ можно получить [здесь](https://pvs-studio.ru/ru/pvs-studio/try-free/)\. Процесс установки в разном окружении описан в документации:

* [установка PVS\-Studio на Windows](https://pvs-studio.ru/ru/docs/manual/0007/#ID14A03AA943);
* [установка PVS\-Studio на Linux](https://pvs-studio.ru/ru/docs/manual/0051/#ID5C47BCCB04);
* [установка PVS\-Studio на macOS](https://pvs-studio.ru/ru/docs/manual/0051/#ID5B1549B6C4)\.

### Развёртывание DefectDojo

DefectDojo можно установить несколькими способами: например, используя Docker\-образ, получить как SaaS или развернуть локально\. Со всеми способами можно ознакомится на [этой странице](https://documentation.defectdojo.com/getting_started/installation/)\.

Посмотрим, как установить DefectDojo с помощью docker\-compose\.yml\. 

Для этого нам понадобится как минимум Docker версии 19\.03\.0 и Docker Compose 1\.28\.0\.

Первым шагом нужно клонировать GitHub репозиторий DefectDojo:

```cpp
git clone https://github.com/DefectDojo/django-DefectDojo.git
```

После этого нужно перейти в директорию django\-DefectDojo и запустить сборку Docker\-образов\.  Для запуска docker\-compose нужно указать параметры '\-\-profile' и '\-\-env\-file'\. 

* **\-\-profile**: отвечает за то, какую базу данных \(MySQL или PostgreSQL\) и брокер сообщений \(RabbitMQ или Redis\) будет использовать DefectDojo\.
* **\-\-env\-file**: путь до файла с параметрами окружения для выбранных базы и брокера\. 

В этом варианте я использую комбинацию PostgreSQL и RabbitMQ\. Команда запуска docker\-compose будет выглядеть следующим образом: 

```cpp
docker-compose --profile postgres-rabbitmq ^
  --env-file .\docker\enviroment\postgres-rabbitmq.env up
```

После запуска контейнеров в DefectDojo можно зайти из учётной записи администратора\. Чтобы получить пароль администратора, нужно использовать следующую команду:  

```cpp
docker-compose logs initializer | grep "Admin password:"
```

или

```cpp
docker-compose logs initializer | find "Admin password:"
```

По умолчанию DefectDojo разворачивается на 8080 порте\. Изменить его можно в файле docker\-compose\.yml\. 

### Подготовка DefectDojo для работы с отчётом PVS\-Studio

Для правильной работы отчёта PVS\-Studio в DefectDojo необходимо модифицировать файл 'local\_settings\.py'\. В нашем варианте запуска этот файл должен располагаться в директории /docker/extra\_settings/\. В 'local\_settings\.py' нужно дописать строку: 

```cpp
HASHCODE_FIELDS_PER_SCANNER=
{"PVS-Studio Scan (Generic Findings Import)":["unique_id_from_tool"]}.
```

Благодаря этой настройке DefectDojo понимает, какое поле отчёта использовать для идентификации дубликатов сообщений\.

Также в настройках DefectDojo необходимо включить настройку 'False positive history'\. Она отвечает за то, чтобы информация о ложных срабатываниях сохранялась между отчётами\. 

Теперь, когда DefectDojo развернут, нужно подготовить его для работы с проектами и отчётами\. В качестве тестового проекта будет использоваться открытый проект [COVID\-19 CovidSim Model](https://github.com/mrc-ide/covid-sim), написанный на языке C\+\+\. 

Сперва в DefectDojo нужно создать Product: 'Products'\-\>'Add Product'\.

![1062_Integrating_PVS-Studio_with_DefectDojo_ru/image2.png](https://import.viva64.com/docx/blog/1062_Integrating_PVS-Studio_with_DefectDojo_ru/image2.png)

После этого нужно заполнить информацию о проекте\. Для теста я заполнил только обязательные поля и перенёс описание проекта из его GitHub\-репозитория\.

В созданный Product нужно добавить новый engagement\. Это основная сущность, в которую будет загружаться отчёт анализатора и с которой мы будем работать\.   

В DefectDojo существует два вида engagement'ов: Interactive и CI/CD\. Во второй можно дополнительно передавать информацию из CI/CD системы, например, номер сборки\. На работу с отчётом этот выбор не влияет\. 

![1062_Integrating_PVS-Studio_with_DefectDojo_ru/image3.png](https://import.viva64.com/docx/blog/1062_Integrating_PVS-Studio_with_DefectDojo_ru/image3.png)

Стоит сказать, что существует несколько вариантов работы с результатами анализа\. Один из них — создание нового engagement'а для каждого нового отчёта\. В этом случае следует убедиться, что настройка 'Deduplication within this engagement only' выключена\. Если она будет включена, то при загрузке нового отчёта пропадёт информация о уже размеченных предупреждениях\.

![1062_Integrating_PVS-Studio_with_DefectDojo_ru/image4.png](https://import.viva64.com/docx/blog/1062_Integrating_PVS-Studio_with_DefectDojo_ru/image4.png)

В этом примере я загружаю все отчёты в один engagement\. DefectDojo гибкий инструмент и позволяет настроить workflow под нужды пользователя\.

## Автоматизация загрузки результатов анализа в DefectDojo\.

Для автоматизации процесса проверки и загрузки отчёта в DefectDojo я сделал небольшую Jenkins задачу\. Рассмотрим её подробнее\. 

Первым делом нужно доставить проект covid\-sim и вспомогательный Python\-скрипт на Jenkins\. Для этого добавим в pipeline следующие шаги: 

```cpp
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']]
      ])
    }
  }
}
```

Следующим этапом будет запуск проверки проекта\. Добавим соответствующий шаг в скрипт:

```cpp
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](https://pvs-studio.ru/ru/docs/#ID332F753E10) для получения инструкции по запуску анализа конкретно для вашего случая\.

Код возврата 256 утилиты PVS\-Studio\_Cmd\.exe означает, что в проекте обнаружены потенциальные ошибки\. В результате этого шага будет создан отчёт 'covid\-sim\.plog'  в директории проекта\.

После того как отчёт получен, его необходимо преобразовать в специальный формат\. Добавим шаг конвертации в наш pipeline: 

```cpp
stage('Convert'){
  steps{
    dir('covid-sim'){
      bat """
        PlogConverter.exe -t DefectDojo -a GA:1,2,3 covid-sim.plog
      """
    }
  }
}
```

В этой команде применяются следующие параметры:

* \-t — форматы, в которые будет преобразован отчёт\.
* \-a — фильтр предупреждений\. В нашем случае останутся только предупреждения из группы диагностик общего назначения\.

Формат DefectDojo доступен в PlogConverter, идущем с PVS\-Studio версии 7\.26\. Вы можете узнать больше об утилите конвертации в [документации](https://pvs-studio.ru/ru/docs/manual/0038/)\.

В результате этого шага будет создан отчёт 'covid\-sim\.plog\.defectdojo\.json'\. Его\-то и нужно загрузить в DefectDojo\. Для этого добавим следующий шаг в pipeline:

```cpp
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\. 

![1062_Integrating_PVS-Studio_with_DefectDojo_ru/image5.png](https://import.viva64.com/docx/blog/1062_Integrating_PVS-Studio_with_DefectDojo_ru/image5.png)



![1062_Integrating_PVS-Studio_with_DefectDojo_ru/image6.png](https://import.viva64.com/docx/blog/1062_Integrating_PVS-Studio_with_DefectDojo_ru/image6.png)

## Работа с отчётом PVS\-Studio в DefectDojo

После выполнения предыдущего шага отчёт должен появиться в указанном engagement\. 

![1062_Integrating_PVS-Studio_with_DefectDojo_ru/image7.png](https://import.viva64.com/docx/blog/1062_Integrating_PVS-Studio_with_DefectDojo_ru/image7.png)

Последний загруженный отчёт будет первым в списке \(если в engagement нет отчётов другого типа\)\. При клике на него откроется таблица с предупреждениями анализатора\.

![1062_Integrating_PVS-Studio_with_DefectDojo_ru/image8.png](https://import.viva64.com/docx/blog/1062_Integrating_PVS-Studio_with_DefectDojo_ru/image8.png)



DefectDojo позволяет фильтровать сообщения по разным категориям, включая уровень достоверности, номер CWE, статус, и т\.д\.

При нажатии на поле 'Name' откроется описание предупреждения\.

![1062_Integrating_PVS-Studio_with_DefectDojo_ru/image9.png](https://import.viva64.com/docx/blog/1062_Integrating_PVS-Studio_with_DefectDojo_ru/image9.png)

Здесь можно найти подробное описание ошибки и её расположение\.  

После загрузки отчёта все сообщения будут иметь статус 'Inactive'\. При начале работы с предупреждением поменяйте его статус на 'Active'\. Тогда это сообщение можно будет найти на вкладке 'Findings'\.

![1062_Integrating_PVS-Studio_with_DefectDojo_ru/image10.png](https://import.viva64.com/docx/blog/1062_Integrating_PVS-Studio_with_DefectDojo_ru/image10.png)

После проверки предупреждения отметьте его либо как 'Verified' и 'Mitigated', если вы исправили ошибку, либо как 'False Positive', если предупреждение оказалось ложным\.

![1062_Integrating_PVS-Studio_with_DefectDojo_ru/image11.png](https://import.viva64.com/docx/blog/1062_Integrating_PVS-Studio_with_DefectDojo_ru/image11.png)



Отметим несколько предупреждений как ложные\. На странице с описанием engagement отобразится статистика по тесту\. 

![1062_Integrating_PVS-Studio_with_DefectDojo_ru/image12.png](https://import.viva64.com/docx/blog/1062_Integrating_PVS-Studio_with_DefectDojo_ru/image12.png)

## Quality Gate в DefectDojo

DefectDojo — гибкий инструмент, который можно настроить в соответствии с вашими потребностями\. Это позволяет встроить его в пользовательские процессы\. DefectDojo имеет API для автоматизации и настройки работы в нём\. Посмотрим, как с помощью API можно реализовать такой механизм, как Quality Gate\.

Quality Gate — это индикатор соответствия кода проекта заданным пороговым значениям метрик\. Качество кода и его безопасность неразрывно связаны\. Quality Gate мешает внедрению кода, не соответствующего стандартам\.

Для реализации Quality Gate я написал небольшой python\-скрипт\. Найти и скачать его можно [здесь](https://github.com/viva64/DefectDojo-QualityGate/blob/main/qualitygate.py)\. Скрипт получает последний загруженный отчёт из предоставленного engagement, определяет количество предупреждений по уровням достоверности и сравнивает его с эталонным значением\.

Для автоматизации проверки Quality Gate добавим новый шаг в Jenkins pipeline\.

```cpp
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\.

```cpp
environment {
  DD_HOST = 'http://localhost:8080/'
  DD_API_TOKEN='44ac826dc4f3b6add1161dab11b49402618efaba'
}
```

## Заключение

Как мы увидели, настроить работу с отчётом PVS\-Studio в DefectDojo довольно просто\. В результате мы получаем возможность удобно работать с предупреждениями анализатора и контролировать их исправление\.

Для тех, кто заинтересовался совместным использованием этих продуктов: по этой [ссылке](https://pvs-studio.ru/ru/pvs-studio/try-free/) вы можете скачать анализатор, а [здесь](https://www.defectdojo.org/) узнать больше о DefectDojo\.