Skip to content

Commit

Permalink
make defect dojo able to tag duplicate findings
Browse files Browse the repository at this point in the history
  • Loading branch information
northdpole committed Mar 17, 2024
1 parent 014211d commit b99faf0
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 18 deletions.
8 changes: 6 additions & 2 deletions components/consumers/defectdojo/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,17 +62,21 @@ func (client *Client) CreateFinding(
title, description, severity, target, date, numericalSeverity string,
tags []string,
testID, line, cwe, foundBy int32,
falseP, duplicate, active bool,
falseP, duplicate bool,
cvssScore float64,
) (types.FindingCreateResponse, error) {
url := fmt.Sprintf("%s/findings", client.host)
active := true
if duplicate {
active = false
}
body := types.FindingCreateRequest{
Tags: tags,
Date: date,
Cwe: cwe,
Line: line,
FilePath: target,
Duplicate: false,
Duplicate: duplicate,
FalseP: falseP,
Active: active,
Verified: false,
Expand Down
10 changes: 1 addition & 9 deletions components/consumers/defectdojo/client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package client

import (
"encoding/json"
"io"
"io/ioutil"
"net/http"
"net/http/httptest"
"testing"
Expand Down Expand Up @@ -36,10 +36,8 @@ func TestCreateFinding(t *testing.T) {
called = true
assert.Equal(t, r.Method, "POST")
assert.Equal(t, r.RequestURI, "/findings")

b, err := io.ReadAll(r.Body)
require.NoError(t, err)

var actual, exp types.FindingCreateRequest
exp = types.FindingCreateRequest{
Test: 1,
Expand All @@ -59,11 +57,9 @@ func TestCreateFinding(t *testing.T) {
}
require.NoError(t, json.Unmarshal(b, &actual))
assert.Equal(t, actual, exp)

_, err = w.Write([]byte(expected))
require.NoError(t, err)
}))

c := &Client{host: mockTs.URL, apiToken: "test", user: ""}
_, err := c.CreateFinding("title",
"description",
Expand All @@ -85,10 +81,8 @@ func TestCreateEngagement(t *testing.T) {
called = true
assert.Equal(t, r.Method, "POST")
assert.Equal(t, r.RequestURI, "/engagements")

b, err := io.ReadAll(r.Body)
require.NoError(t, err)

var engagement types.EngagementRequest
require.NoError(t, json.Unmarshal(b, &engagement))

Expand All @@ -101,11 +95,9 @@ func TestCreateEngagement(t *testing.T) {
Product: 2,
}
assert.Equal(t, expectedEngagement, engagement)

_, err = w.Write([]byte(`{"id":4,"tags":["foo.git/somesha"],"name":"dracon scan foo","description":null,"version":"string","first_contacted":null,"target_start":"2022-06-01","target_end":"2022-06-01","reason":null,"updated":"2022-06-01T16:29:18.965507Z","created":"2022-06-01T16:29:18.908694Z","active":true,"tracker":null,"test_strategy":null,"threat_model":true,"api_test":true,"pen_test":true,"check_list":true,"status":"","progress":"threat_model","tmodel_path":"none","done_testing":false,"engagement_type":"Interactive","build_id":"foo","commit_hash":null,"branch_tag":null,"source_code_management_uri":null,"deduplication_on_engagement":false,"lead":null,"requester":null,"preset":null,"report_type":null,"product":2,"build_server":null,"source_code_management_server":null,"orchestration_engine":null,"notes":[],"files":[],"risk_acceptance":[]}`))
require.NoError(t, err)
}))

c := &Client{host: mockTs.URL, apiToken: "test", user: ""}
_, err := c.CreateEngagement("dracon scan foo", "2022-06-01", []string{"foo.git/somesha"}, 2)
require.NoError(t, err)
Expand Down
2 changes: 0 additions & 2 deletions components/consumers/defectdojo/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ func handleRawResults(product int, dojoClient *client.Client, responses []*v1.La
dojoClient.UserID,
false,
false,
true,
iss.GetCvss())
if err != nil {
log.Fatalf("Could not create raw finding error: %v\n", err)
Expand Down Expand Up @@ -129,7 +128,6 @@ func handleEnrichedResults(product int, dojoClient *client.Client, responses []*
test.ID, 0, 0, dojoClient.UserID,
iss.GetFalsePositive(),
duplicate,
true,
rawIss.GetCvss())
if err != nil {
log.Fatalf("Could not create enriched finding error: %v\n", err)
Expand Down
20 changes: 15 additions & 5 deletions components/consumers/defectdojo/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ func createObjects(product int, scanType string) ([]*v1.LaunchToolResponse, []*t
var issues []*v1.Issue
var enrichedIssues []*v1.EnrichedIssue
for j := 0; j <= 3%(i+1); j++ {
duplicateTimes, _ := time.Parse(time.RFC3339, "2000-01-19T18:09:06.370037788Z")
duplicateTimestamp := timestamppb.New(duplicateTimes)
x := v1.Issue{
Target: fmt.Sprintf("myTarget %d-%d", i, j),
Type: fmt.Sprintf("type %d-%d", i, j),
Expand All @@ -72,7 +74,7 @@ func createObjects(product int, scanType string) ([]*v1.LaunchToolResponse, []*t
y := v1.EnrichedIssue{
RawIssue: &x,
FirstSeen: response.ScanInfo.ScanStartTime,
Count: uint64(i),
Count: 1,
FalsePositive: false,
UpdatedAt: response.ScanInfo.ScanStartTime,
Hash: "d41d8cd98f00b204e9800998ecf8427e",
Expand All @@ -81,6 +83,10 @@ func createObjects(product int, scanType string) ([]*v1.LaunchToolResponse, []*t
"Policy.Blah.Decision": "failed",
},
}
if j%2 == 0 {
y.FirstSeen = duplicateTimestamp
y.Count = uint64(j)
}
issues = append(issues, &x)
enrichedIssues = append(enrichedIssues, &y)

Expand All @@ -98,7 +104,7 @@ func createObjects(product int, scanType string) ([]*v1.LaunchToolResponse, []*t
}
d = desc
}
findingsRequests = append(findingsRequests, &types.FindingCreateRequest{
findingsReq := &types.FindingCreateRequest{
Tags: []string{"DraconScan", scanType + "Finding", scanID, toolName},
Title: x.Title,
Date: times.Format(DojoTimeFormat),
Expand All @@ -108,7 +114,13 @@ func createObjects(product int, scanType string) ([]*v1.LaunchToolResponse, []*t
FoundBy: []int32{1},
Description: *d,
Active: true,
})
Duplicate: false,
}
if j%2 == 0 && scanType != "Raw" {
findingsReq.Active = false
findingsReq.Duplicate = true
}
findingsRequests = append(findingsRequests, findingsReq)
}
response.Issues = issues
enrichedResponse.OriginalResults = response // duplication here is important since we use this enrichedResponse in getEnrichedIssues above
Expand Down Expand Up @@ -156,7 +168,6 @@ func TestHandleRawResults(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
require.NoError(t, err)

switch string(r.URL.Path) {
case "/users":
assert.Equal(t, r.Method, http.MethodGet)
Expand Down Expand Up @@ -230,7 +241,6 @@ func TestHandleEnrichedResults(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
require.NoError(t, err)

switch string(r.URL.String()) {
case "/users":
assert.Equal(t, r.Method, http.MethodGet)
Expand Down

0 comments on commit b99faf0

Please sign in to comment.