diff --git a/pkg/model/summary.go b/pkg/model/summary.go index 036df88fd66..98212726cdc 100644 --- a/pkg/model/summary.go +++ b/pkg/model/summary.go @@ -89,9 +89,10 @@ type Summary struct { Counters SeveritySummary Times - ScannedPaths []string `json:"paths"` - Queries QueryResultSlice `json:"queries"` - Bom QueryResultSlice `json:"bill_of_materials,omitempty"` + ScannedPaths []string `json:"paths"` + Queries QueryResultSlice `json:"queries"` + Bom QueryResultSlice `json:"bill_of_materials,omitempty"` + FilePaths map[string]string `json:"-"` } // PathParameters - structure wraps the required fields for temporary path translation @@ -180,6 +181,8 @@ func CreateSummary(counters Counters, vulnerabilities []Vulnerability, severitySummary := SeveritySummary{ ScanID: scanID, } + filePaths := make(map[string]string) + for i := range vulnerabilities { item := vulnerabilities[i] if _, ok := q[item.QueryID]; !ok { @@ -196,9 +199,11 @@ func CreateSummary(counters Counters, vulnerabilities []Vulnerability, } } + resolvedPath := resolvePath(item.FileName, pathExtractionMap) + qItem := q[item.QueryID] qItem.Files = append(qItem.Files, VulnerableFile{ - FileName: resolvePath(item.FileName, pathExtractionMap), + FileName: resolvedPath, SimilarityID: item.SimilarityID, Line: item.Line, VulnLines: item.VulnLines, @@ -210,6 +215,8 @@ func CreateSummary(counters Counters, vulnerabilities []Vulnerability, Value: item.Value, }) + filePaths[resolvedPath] = item.FileName + q[item.QueryID] = qItem } @@ -251,5 +258,6 @@ func CreateSummary(counters Counters, vulnerabilities []Vulnerability, SeveritySummary: severitySummary, ScannedPaths: removeAllURLCredentials(pathExtractionMap), LatestVersion: version, + FilePaths: filePaths, } } diff --git a/pkg/model/summary_test.go b/pkg/model/summary_test.go index d64c1110669..2324cee252e 100644 --- a/pkg/model/summary_test.go +++ b/pkg/model/summary_test.go @@ -55,10 +55,13 @@ func TestCreateSummary(t *testing.T) { Bom: []QueryResult{}, Queries: []QueryResult{}, ScannedPaths: []string{}, + FilePaths: make(map[string]string), }) }) t.Run("create_summary", func(t *testing.T) { + filePaths := make(map[string]string) + filePaths["fileName"] = "fileName" summary := CreateSummary(counter, vulnerabilities, "scanID", pathExtractionMap, Version{}) require.Equal(t, summary, Summary{ Counters: counter, @@ -93,6 +96,7 @@ func TestCreateSummary(t *testing.T) { }, }, ScannedPaths: []string{}, + FilePaths: filePaths, }) }) } diff --git a/pkg/report/cyclonedx.go b/pkg/report/cyclonedx.go index 478e5470900..a1f3bfc95e4 100644 --- a/pkg/report/cyclonedx.go +++ b/pkg/report/cyclonedx.go @@ -3,22 +3,28 @@ package report import ( "strings" + "github.com/Checkmarx/kics/pkg/model" reportModel "github.com/Checkmarx/kics/pkg/report/model" ) // PrintCycloneDxReport prints the CycloneDX report in the given path and filename with the given body func PrintCycloneDxReport(path, filename string, body interface{}) error { + filePaths := make(map[string]string) + if !strings.HasPrefix(filename, "cyclonedx-") { filename = "cyclonedx-" + filename } if body != "" { + if s, ok := body.(*model.Summary); ok { + filePaths = s.FilePaths + } summary, err := getSummary(body) if err != nil { return err } - body = reportModel.BuildCycloneDxReport(&summary) + body = reportModel.BuildCycloneDxReport(&summary, filePaths) } return exportXMLReport(path, filename, body) diff --git a/pkg/report/model/cyclonedx.go b/pkg/report/model/cyclonedx.go index e6759bac163..6ded5ba081e 100644 --- a/pkg/report/model/cyclonedx.go +++ b/pkg/report/model/cyclonedx.go @@ -128,11 +128,12 @@ func getAllFiles(summary *model.Summary) []model.VulnerableFile { return fileNames } -func generateSha256(filePath string) string { - content, err := os.ReadFile(filepath.Clean(filePath)) +func generateSha256(filePath string, filePaths map[string]string) string { + file := filePaths[filePath] + content, err := os.ReadFile(filepath.Clean(file)) if err != nil { - log.Trace().Msgf("failed to read %s", filePath) + log.Trace().Msgf("failed to read %s", file) return "" } @@ -224,7 +225,7 @@ func InitCycloneDxReport() *CycloneDxReport { } // BuildCycloneDxReport builds the CycloneDX report -func BuildCycloneDxReport(summary *model.Summary) *CycloneDxReport { +func BuildCycloneDxReport(summary *model.Summary, filePaths map[string]string) *CycloneDxReport { var component Component var vuln []Vulnerability var version, sha, purl, filePath string @@ -234,7 +235,7 @@ func BuildCycloneDxReport(summary *model.Summary) *CycloneDxReport { for i := range files { filePath = strings.Replace(files[i].FileName, "\\", "/", -1) - sha = generateSha256(filePath) + sha = generateSha256(files[i].FileName, filePaths) index := 12 if len(sha) < index { diff --git a/pkg/report/model/cyclonedx_test.go b/pkg/report/model/cyclonedx_test.go index b2324eeeeaf..fedf3487ea6 100644 --- a/pkg/report/model/cyclonedx_test.go +++ b/pkg/report/model/cyclonedx_test.go @@ -181,8 +181,16 @@ func TestBuildCycloneDxReport(t *testing.T) { cycloneDx.Components.Components = append(cycloneDx.Components.Components, c2) cycloneDx.Components.Components = append(cycloneDx.Components.Components, c1) + filePaths := make(map[string]string) + + file1 := filepath.Join("..", "..", "..", "assets", "queries", "terraform", "aws", "guardduty_detector_disabled", "test", "positive.tf") + file2 := filepath.Join("..", "..", "..", "assets", "queries", "terraform", "aws", "guardduty_detector_disabled", "test", "negative.tf") + filePaths[file1] = file1 + filePaths[file2] = file2 + type args struct { - summary *model.Summary + summary *model.Summary + filePaths map[string]string } tests := []struct { name string @@ -192,7 +200,8 @@ func TestBuildCycloneDxReport(t *testing.T) { { name: "Build CycloneDX report", args: args{ - summary: &test.ExampleSummaryMock, + summary: &test.ExampleSummaryMock, + filePaths: filePaths, }, want: &cycloneDx, }, @@ -205,7 +214,7 @@ func TestBuildCycloneDxReport(t *testing.T) { queries[idx].Files[i].FileName = filepath.Join("..", "..", "..", queries[idx].Files[i].FileName) } } - got := BuildCycloneDxReport(tt.args.summary) + got := BuildCycloneDxReport(tt.args.summary, tt.args.filePaths) got.SerialNumber = "urn:uuid:" // set to "urn:uuid:" because it will be different for every report if !reflect.DeepEqual(got, tt.want) { t.Errorf("BuildCycloneDxReport() = %v, want %v", got, tt.want) diff --git a/pkg/scan/post_scan.go b/pkg/scan/post_scan.go index 6ae91f55e34..28a21e49194 100644 --- a/pkg/scan/post_scan.go +++ b/pkg/scan/post_scan.go @@ -113,6 +113,8 @@ func (c *Client) postScan(scanResults *Results) error { return err } + deleteExtractionFolder(scanResults.ExtractedPaths.ExtractionMap) + consolePrinter.PrintScanDuration(time.Since(c.ScanStartTime)) printVersionCheck(c.Printer, &summary) diff --git a/pkg/scan/scan.go b/pkg/scan/scan.go index 6c816e9a9c6..9af75b076bb 100644 --- a/pkg/scan/scan.go +++ b/pkg/scan/scan.go @@ -154,8 +154,6 @@ func (c *Client) executeScan(ctx context.Context) (*Results, error) { return nil, err } - deleteExtractionFolder(executeScanParameters.extractedPaths.ExtractionMap) - return &Results{ Results: results, ExtractedPaths: executeScanParameters.extractedPaths,