Алгоритм дедупликации
Finding — это результат одного сканирования, который содержит информацию об уязвимости. Finding считается родительским, если это является первой находкой для уязвимости, она создает issue.
Issue — это сущность в Vampy, которая содержит всю информацию об уязвимости, полученную из finding.
Finding считается duplicate, если во время импорта и работы алгоритма дедупликации была найдена совпадающая существующая issue. В этом случае дубликат finding связывается с issue.
Если дубликат определен, он связывается с issue и отображается в разделе Duplicate. Данные в issue берутся из родительской finding, дубликаты finding не обновляют их. Единственное поле, которое может быть обновлено — это solution.
Дедубликация — это алгоритм, который помогает Vampy распознавать идентичные issues в результатах сканирования.
Результат сканирования содержит несколько findings, которые включают в себя несколько полей, в зависимости от сканера. Обычно все сканы содержат repository name, branch name и внутренний дубликат отпечатка сканера — SD ID, но некоторые поля специфичны для различных видов сканеров.
SAST | SCA | DAST |
---|---|---|
CVE | CVE | CVE |
CWE | CWE | CWE |
file path | file path | IP |
file line number | file line number | domain name |
code snippet | library name | |
library version |
Основная проблема заключается в том, что не все сканеры заполняют эти поля, поэтому иногда мы можем получить несколько finding от разных сканеров, которые в основном ссылаются на одну и ту же issue. Для каждой finding Vampy создает несколько хешей на основе полей, которые содержит данная finding. Они используются для сравнения findings с существующими issues, чтобы выяснить, получили ли мы дубликат или нам нужно создать новую issue.
Таким образом, мы создаем следующие хеши для каждой finding
Приоритет для сравнения | SAST | SCA | DAST |
---|---|---|---|
1 | repository + branch + SD ID (required SD ID) |
repository + branch + SD ID (required SD ID) |
repository + branch + SD ID (required SD ID) |
2 | repository + branch + CVE + CWE + filepath + code snippet (необходимы поля filepath и code snippet) |
repository + branch + CVE + CWE + filepath + file line number + library name + library version (необходимы поля library name и library version) |
repository + branch + CVE + CWE + domain name + IP address (необходимо поле CVE) |
3 | repository + branch + CVE + CWE + filepath + file line number (необходимы поля filepath и file line number) |
repository + branch + CVE + CWE + filepath + file line number + library name (необходимы поля library name и пустое для поиска поле library version) |
repository + branch + CVE + CWE + title |
4 | repository + branch + CVE + CWE + filepath + file line number + code_snippet + title | repository + branch + CVE + CWE + filepath + file line number + library name + library version + title |
Когда новые findings связываются с существующей issue, то и их хеши также связываются. В итоге мы имеем issue, которая имеет несколько хешей, полученных из всех findings, связанных с ней.
Примеры
SAST
Допустим, у нас есть 2 findings: A в качестве родительской и B как finding, которую нужно проверить на дубликат. У них есть все поля для SAST, A была найдена с помощью Semgrep, а B — с помощью Checkmarx. Как это выглядит в нашей системе? Красные стрелки показывают путь для наших примеров.
Здесь мы видим, что они не совпадают, поскольку у них разные отпечатки, полученные от разных сканеров. Но когда мы проверяем другие поля, мы понимаем, что это одна и та же issue.
SCA
Мы нашли Finding A, с заполненными полями. Он описывает уязвимость в кусочке кода, поддерживаемом библиотекой версии 1.0. Мы обновили версию библиотеки до 1.1, но уязвимость никуда не делась, и следующий скан выявляет Finding B.
Схема выглядит довольно просто.
Статусы issue
В основном существует 4 статуса для issues:
- New Issue,
- Recurrent,
- Fixed,
- Reopened.
Когда мы загружаем новый скан и алгоритм находит дубликаты, он превращает New Issue в Recurrent и Fixed в Reopened.
Когда алгоритм не находит дубликатов для существующих issues, он устанавливает все из них в статус Fixed.