diff --git a/pkg/printer/printer_test.go b/pkg/printer/printer_test.go index 42a49874d78..bd91aab06dc 100644 --- a/pkg/printer/printer_test.go +++ b/pkg/printer/printer_test.go @@ -111,20 +111,20 @@ var printTests = []struct { { caseTest: test.ComplexSummaryMock, - expectedResult: "\n\nAMI Not Encrypted, Severity: HIGH, Results: 2\n\t[1]: positive.tf:30\n\t[2]: positive.tf:35\nAmazonMQ Broker Encryption Disabled, Severity: MEDIUM, Results: 1\n\t[1]: positive.tf:1\nALB protocol is HTTP, Severity: HIGH, Results: 2\n\t[1]: positive.tf:25\n\t[2]: positive.tf:19\n\nResults Summary:\nHIGH: 4\nMEDIUM: 1\nLOW: 0\nINFO: 0\nTOTAL: 5\n\n", - expectedResultFull: "\n\nAMI Not Encrypted, Severity: HIGH, Results: 2\nDescription: AWS AMI Encryption is not enabled\nPlatform: \nCWE: 22\nLearn more about this vulnerability: https://docs.kics.io/latest/queries/-queries/97707503-a22c-4cd7-b7c0-f088fa7cf830\n\n\t[1]: positive.tf:30\n\n\n\n\t[2]: positive.tf:35\n\n\n\nAmazonMQ Broker Encryption Disabled, Severity: MEDIUM, Results: 1\nDescription: AmazonMQ Broker should have Encryption Options defined\nPlatform: \nLearn more about this vulnerability: https://docs.kics.io/latest/queries/-queries/aws/3db3f534-e3a3-487f-88c7-0a9fbf64b702\n\n\t[1]: positive.tf:1\n\n\n\nALB protocol is HTTP, Severity: HIGH, Results: 2\nDescription: ALB protocol is HTTP Description\nPlatform: \nLearn more about this vulnerability: https://docs.kics.io/latest/queries/-queries/de7f5e83-da88-4046-871f-ea18504b1d43\n\n\t[1]: positive.tf:25\n\n\n\n\t[2]: positive.tf:19\n\n\n\n\nResults Summary:\nHIGH: 4\nMEDIUM: 1\nLOW: 0\nINFO: 0\nTOTAL: 5\n\n", + expectedResult: "\n\nAMI Not Encrypted, Severity: HIGH, Results: 2\n\t[1]: positive.tf:35\n\t[2]: positive.tf:30\nAmazonMQ Broker Encryption Disabled, Severity: MEDIUM, Results: 1\n\t[1]: positive.tf:1\nALB protocol is HTTP, Severity: HIGH, Results: 2\n\t[1]: positive.tf:19\n\t[2]: positive.tf:25\n\nResults Summary:\nHIGH: 4\nMEDIUM: 1\nLOW: 0\nINFO: 0\nTOTAL: 5\n\n", + expectedResultFull: "\n\nAMI Not Encrypted, Severity: HIGH, Results: 2\nDescription: AWS AMI Encryption is not enabled\nPlatform: \nCWE: 22\nLearn more about this vulnerability: https://docs.kics.io/latest/queries/-queries/97707503-a22c-4cd7-b7c0-f088fa7cf830\n\n\t[1]: positive.tf:35\n\n\n\n\t[2]: positive.tf:30\n\n\n\nAmazonMQ Broker Encryption Disabled, Severity: MEDIUM, Results: 1\nDescription: AmazonMQ Broker should have Encryption Options defined\nPlatform: \nLearn more about this vulnerability: https://docs.kics.io/latest/queries/-queries/aws/3db3f534-e3a3-487f-88c7-0a9fbf64b702\n\n\t[1]: positive.tf:1\n\n\n\nALB protocol is HTTP, Severity: HIGH, Results: 2\nDescription: ALB protocol is HTTP Description\nPlatform: \nLearn more about this vulnerability: https://docs.kics.io/latest/queries/-queries/de7f5e83-da88-4046-871f-ea18504b1d43\n\n\t[1]: positive.tf:19\n\n\n\n\t[2]: positive.tf:25\n\n\n\n\nResults Summary:\nHIGH: 4\nMEDIUM: 1\nLOW: 0\nINFO: 0\nTOTAL: 5\n\n", customQueries: false, }, { caseTest: test.ComplexSummaryMock, - expectedResult: "\n\nAMI Not Encrypted, Severity: HIGH, Results: 2\n\t[1]: positive.tf:30\n\t[2]: positive.tf:35\nAmazonMQ Broker Encryption Disabled, Severity: MEDIUM, Results: 1\n\t[1]: positive.tf:1\nALB protocol is HTTP, Severity: HIGH, Results: 2\n\t[1]: positive.tf:25\n\t[2]: positive.tf:19\n\nResults Summary:\nHIGH: 4\nMEDIUM: 1\nLOW: 0\nINFO: 0\nTOTAL: 5\n\n", - expectedResultFull: "\n\nAMI Not Encrypted, Severity: HIGH, Results: 2\nDescription: AWS AMI Encryption is not enabled\nPlatform: \nCWE: 22\n\t[1]: positive.tf:30\n\n\n\n\t[2]: positive.tf:35\n\n\n\nAmazonMQ Broker Encryption Disabled, Severity: MEDIUM, Results: 1\nDescription: AmazonMQ Broker should have Encryption Options defined\nPlatform: \n\t[1]: positive.tf:1\n\n\n\nALB protocol is HTTP, Severity: HIGH, Results: 2\nDescription: ALB protocol is HTTP Description\nPlatform: \n\t[1]: positive.tf:25\n\n\n\n\t[2]: positive.tf:19\n\n\n\n\nResults Summary:\nHIGH: 4\nMEDIUM: 1\nLOW: 0\nINFO: 0\nTOTAL: 5\n\n", + expectedResult: "\n\nAMI Not Encrypted, Severity: HIGH, Results: 2\n\t[1]: positive.tf:35\n\t[2]: positive.tf:30\nAmazonMQ Broker Encryption Disabled, Severity: MEDIUM, Results: 1\n\t[1]: positive.tf:1\nALB protocol is HTTP, Severity: HIGH, Results: 2\n\t[1]: positive.tf:19\n\t[2]: positive.tf:25\n\nResults Summary:\nHIGH: 4\nMEDIUM: 1\nLOW: 0\nINFO: 0\nTOTAL: 5\n\n", + expectedResultFull: "\n\nAMI Not Encrypted, Severity: HIGH, Results: 2\nDescription: AWS AMI Encryption is not enabled\nPlatform: \nCWE: 22\n\t[1]: positive.tf:35\n\n\n\n\t[2]: positive.tf:30\n\n\n\nAmazonMQ Broker Encryption Disabled, Severity: MEDIUM, Results: 1\nDescription: AmazonMQ Broker should have Encryption Options defined\nPlatform: \n\t[1]: positive.tf:1\n\n\n\nALB protocol is HTTP, Severity: HIGH, Results: 2\nDescription: ALB protocol is HTTP Description\nPlatform: \n\t[1]: positive.tf:19\n\n\n\n\t[2]: positive.tf:25\n\n\n\n\nResults Summary:\nHIGH: 4\nMEDIUM: 1\nLOW: 0\nINFO: 0\nTOTAL: 5\n\n", customQueries: true, }, { caseTest: test.ComplexSummaryMockWithExperimental, - expectedResult: "\n\nAmazonMQ Broker Encryption Disabled, Severity: MEDIUM, Results: 1\n\t[1]: positive.tf:1\nALB protocol is HTTP, Severity: HIGH, Results: 2\nNote: this is an experimental query\n\t[1]: positive.tf:25\n\t[2]: positive.tf:19\n\nResults Summary:\nHIGH: 2\nMEDIUM: 1\nLOW: 0\nINFO: 0\nTOTAL: 3\n\n", - expectedResultFull: "\n\nAmazonMQ Broker Encryption Disabled, Severity: MEDIUM, Results: 1\nDescription: AmazonMQ Broker should have Encryption Options defined\nPlatform: \nLearn more about this vulnerability: https://docs.kics.io/latest/queries/-queries/aws/3db3f534-e3a3-487f-88c7-0a9fbf64b702\n\n\t[1]: positive.tf:1\n\n\n\nALB protocol is HTTP, Severity: HIGH, Results: 2\nNote: this is an experimental query\nDescription: ALB protocol is HTTP Description\nPlatform: \nLearn more about this vulnerability: https://docs.kics.io/latest/queries/-queries/de7f5e83-da88-4046-871f-ea18504b1d43\n\n\t[1]: positive.tf:25\n\n\n\n\t[2]: positive.tf:19\n\n\n\n\nResults Summary:\nHIGH: 2\nMEDIUM: 1\nLOW: 0\nINFO: 0\nTOTAL: 3\n\n", + expectedResult: "\n\nAmazonMQ Broker Encryption Disabled, Severity: MEDIUM, Results: 1\n\t[1]: positive.tf:1\nALB protocol is HTTP, Severity: HIGH, Results: 2\nNote: this is an experimental query\n\t[1]: positive.tf:19\n\t[2]: positive.tf:25\n\nResults Summary:\nHIGH: 2\nMEDIUM: 1\nLOW: 0\nINFO: 0\nTOTAL: 3\n\n", + expectedResultFull: "\n\nAmazonMQ Broker Encryption Disabled, Severity: MEDIUM, Results: 1\nDescription: AmazonMQ Broker should have Encryption Options defined\nPlatform: \nLearn more about this vulnerability: https://docs.kics.io/latest/queries/-queries/aws/3db3f534-e3a3-487f-88c7-0a9fbf64b702\n\n\t[1]: positive.tf:1\n\n\n\nALB protocol is HTTP, Severity: HIGH, Results: 2\nNote: this is an experimental query\nDescription: ALB protocol is HTTP Description\nPlatform: \nLearn more about this vulnerability: https://docs.kics.io/latest/queries/-queries/de7f5e83-da88-4046-871f-ea18504b1d43\n\n\t[1]: positive.tf:19\n\n\n\n\t[2]: positive.tf:25\n\n\n\n\nResults Summary:\nHIGH: 2\nMEDIUM: 1\nLOW: 0\nINFO: 0\nTOTAL: 3\n\n", customQueries: false, }, } diff --git a/pkg/report/json.go b/pkg/report/json.go index 749f169b080..613591b647f 100644 --- a/pkg/report/json.go +++ b/pkg/report/json.go @@ -1,6 +1,10 @@ package report -import "github.com/Checkmarx/kics/internal/constants" +import ( + "sort" + + "github.com/Checkmarx/kics/internal/constants" +) const jsonExtension = ".json" @@ -11,12 +15,42 @@ func PrintJSONReport(path, filename string, body interface{}) error { if err != nil { return err } - for idx := range summary.Queries { - summary.Queries[idx].CISBenchmarkName = "" - summary.Queries[idx].CISBenchmarkVersion = "" - summary.Queries[idx].CISDescriptionID = "" - summary.Queries[idx].CISDescriptionText = "" - summary.Queries[idx].CISRationaleText = "" + + queries := summary.Queries + sort.SliceStable(queries, func(i, j int) bool { + if queries[i].Severity == queries[j].Severity { + return queries[i].QueryName < queries[j].QueryName + } + + return false + }) + + for idx := range queries { + queries[idx].CISBenchmarkName = "" + queries[idx].CISBenchmarkVersion = "" + queries[idx].CISDescriptionID = "" + queries[idx].CISDescriptionText = "" + queries[idx].CISRationaleText = "" + + files := queries[idx].Files + sort.Slice(files, func(i, j int) bool { + if files[i].FileName != files[j].FileName { + return files[i].FileName < files[j].FileName + } + + if files[i].SimilarityID != files[j].SimilarityID { + return files[i].SimilarityID < files[j].SimilarityID + } + + if files[i].IssueType != files[j].IssueType { + return files[i].IssueType < files[j].IssueType + } + + return files[i].KeyExpectedValue < files[j].KeyExpectedValue + }) + + queries[idx].Files = files + summary.Queries = queries } summary.Version = constants.Version body = summary diff --git a/pkg/report/model/code_climate_test.go b/pkg/report/model/code_climate_test.go index 368568fcf11..03a40f5f6b1 100644 --- a/pkg/report/model/code_climate_test.go +++ b/pkg/report/model/code_climate_test.go @@ -25,7 +25,7 @@ func TestBuildCodeClimateReport(t *testing.T) { Categories: []string{"Security"}, Location: location{ Path: "positive.tf", - Lines: lines{Begin: 25}, + Lines: lines{Begin: 19}, }, Severity: "critical", CWE: "", @@ -37,7 +37,7 @@ func TestBuildCodeClimateReport(t *testing.T) { Categories: []string{"Security"}, Location: location{ Path: "positive.tf", - Lines: lines{Begin: 19}, + Lines: lines{Begin: 25}, }, Severity: "critical", CWE: "", @@ -55,7 +55,7 @@ func TestBuildCodeClimateReport(t *testing.T) { Categories: []string{"Security"}, Location: location{ Path: "positive.tf", - Lines: lines{Begin: 30}, + Lines: lines{Begin: 35}, }, Severity: "critical", CWE: "22", @@ -67,7 +67,7 @@ func TestBuildCodeClimateReport(t *testing.T) { Categories: []string{"Security"}, Location: location{ Path: "positive.tf", - Lines: lines{Begin: 35}, + Lines: lines{Begin: 30}, }, Severity: "critical", CWE: "22", diff --git a/pkg/report/model/csv_test.go b/pkg/report/model/csv_test.go index 225ca35e449..57dd7bcf136 100644 --- a/pkg/report/model/csv_test.go +++ b/pkg/report/model/csv_test.go @@ -29,11 +29,11 @@ func TestBuildCSVReport(t *testing.T) { CISDescriptionTitle: "testCISTitle", CISDescriptionTextFormatted: "testCISDescription", FileName: "positive.tf", - Line: 25, - IssueType: "MissingAttribute", + Line: 19, + IssueType: "IncorrectValue", SearchKey: "aws_alb_listener[front_end].default_action.redirect", ExpectedValue: "'default_action.redirect.protocol' is equal 'HTTPS'", - ActualValue: "'default_action.redirect.protocol' is missing", + ActualValue: "'default_action.redirect.protocol' is equal 'HTTP'", }, { QueryName: "ALB protocol is HTTP", @@ -46,11 +46,11 @@ func TestBuildCSVReport(t *testing.T) { CISDescriptionTitle: "testCISTitle", CISDescriptionTextFormatted: "testCISDescription", FileName: "positive.tf", - Line: 19, - IssueType: "IncorrectValue", + Line: 25, + IssueType: "MissingAttribute", SearchKey: "aws_alb_listener[front_end].default_action.redirect", ExpectedValue: "'default_action.redirect.protocol' is equal 'HTTPS'", - ActualValue: "'default_action.redirect.protocol' is equal 'HTTP'", + ActualValue: "'default_action.redirect.protocol' is missing", }, }, }, @@ -69,11 +69,11 @@ func TestBuildCSVReport(t *testing.T) { CISDescriptionTitle: "testCISTitle", CISDescriptionTextFormatted: "testCISDescription", FileName: "positive.tf", - Line: 30, - IssueType: "MissingAttribute", + Line: 35, + IssueType: "IncorrectValue", SearchKey: "aws_alb_listener[front_end].default_action.redirect", ExpectedValue: "'default_action.redirect.protocol' is equal 'HTTPS'", - ActualValue: "'default_action.redirect.protocol' is missing", + ActualValue: "'default_action.redirect.protocol' is equal 'HTTP'", }, { QueryName: "AMI Not Encrypted", @@ -86,11 +86,11 @@ func TestBuildCSVReport(t *testing.T) { CISDescriptionTitle: "testCISTitle", CISDescriptionTextFormatted: "testCISDescription", FileName: "positive.tf", - Line: 35, - IssueType: "IncorrectValue", + Line: 30, + IssueType: "MissingAttribute", SearchKey: "aws_alb_listener[front_end].default_action.redirect", ExpectedValue: "'default_action.redirect.protocol' is equal 'HTTPS'", - ActualValue: "'default_action.redirect.protocol' is equal 'HTTP'", + ActualValue: "'default_action.redirect.protocol' is missing", }, }, }, diff --git a/pkg/report/model/sonarqube_test.go b/pkg/report/model/sonarqube_test.go index de428bdb5ef..5f53877d1d3 100644 --- a/pkg/report/model/sonarqube_test.go +++ b/pkg/report/model/sonarqube_test.go @@ -72,7 +72,7 @@ func TestSonarQubeReportBuilder_BuildReport(t *testing.T) { Message: "ALB protocol is HTTP Description", FilePath: "positive.tf", TextRange: &Range{ - StartLine: 25, + StartLine: 19, }, }, SecondaryLocations: []*Location{ @@ -80,7 +80,7 @@ func TestSonarQubeReportBuilder_BuildReport(t *testing.T) { Message: "ALB protocol is HTTP Description", FilePath: "positive.tf", TextRange: &Range{ - StartLine: 19, + StartLine: 25, }, }, }, @@ -111,7 +111,7 @@ func TestSonarQubeReportBuilder_BuildReport(t *testing.T) { Message: "AWS AMI Encryption is not enabled", FilePath: "positive.tf", TextRange: &Range{ - StartLine: 30, + StartLine: 35, }, }, SecondaryLocations: []*Location{ @@ -119,7 +119,7 @@ func TestSonarQubeReportBuilder_BuildReport(t *testing.T) { Message: "AWS AMI Encryption is not enabled", FilePath: "positive.tf", TextRange: &Range{ - StartLine: 35, + StartLine: 30, }, }, }, diff --git a/test/helpers.go b/test/helpers.go index d8478ea091a..faa2586e348 100644 --- a/test/helpers.go +++ b/test/helpers.go @@ -120,21 +120,21 @@ var queryHigh = model.QueryResult{ //nolint Files: []model.VulnerableFile{ { FileName: positive, - Line: 25, - IssueType: "MissingAttribute", + Line: 19, + IssueType: "IncorrectValue", SearchKey: "aws_alb_listener[front_end].default_action.redirect", KeyExpectedValue: "'default_action.redirect.protocol' is equal 'HTTPS'", - KeyActualValue: "'default_action.redirect.protocol' is missing", + KeyActualValue: "'default_action.redirect.protocol' is equal 'HTTP'", Value: nil, VulnLines: &[]model.CodeLine{}, }, { FileName: positive, - Line: 19, - IssueType: "IncorrectValue", + Line: 25, + IssueType: "MissingAttribute", SearchKey: "aws_alb_listener[front_end].default_action.redirect", KeyExpectedValue: "'default_action.redirect.protocol' is equal 'HTTPS'", - KeyActualValue: "'default_action.redirect.protocol' is equal 'HTTP'", + KeyActualValue: "'default_action.redirect.protocol' is missing", Value: nil, VulnLines: &[]model.CodeLine{}, }, @@ -228,21 +228,21 @@ var queryHighExperimental = model.QueryResult{ Files: []model.VulnerableFile{ { FileName: positive, - Line: 25, - IssueType: "MissingAttribute", + Line: 19, + IssueType: "IncorrectValue", SearchKey: "aws_alb_listener[front_end].default_action.redirect", KeyExpectedValue: "'default_action.redirect.protocol' is equal 'HTTPS'", - KeyActualValue: "'default_action.redirect.protocol' is missing", + KeyActualValue: "'default_action.redirect.protocol' is equal 'HTTP'", Value: nil, VulnLines: &[]model.CodeLine{}, }, { FileName: positive, - Line: 19, - IssueType: "IncorrectValue", + Line: 25, + IssueType: "MissingAttribute", SearchKey: "aws_alb_listener[front_end].default_action.redirect", KeyExpectedValue: "'default_action.redirect.protocol' is equal 'HTTPS'", - KeyActualValue: "'default_action.redirect.protocol' is equal 'HTTP'", + KeyActualValue: "'default_action.redirect.protocol' is missing", Value: nil, VulnLines: &[]model.CodeLine{}, }, @@ -304,21 +304,21 @@ var queryHighCWE = model.QueryResult{ //nolint Files: []model.VulnerableFile{ { FileName: positive, - Line: 30, - IssueType: "MissingAttribute", + Line: 35, + IssueType: "IncorrectValue", SearchKey: "aws_alb_listener[front_end].default_action.redirect", KeyExpectedValue: "'default_action.redirect.protocol' is equal 'HTTPS'", - KeyActualValue: "'default_action.redirect.protocol' is missing", + KeyActualValue: "'default_action.redirect.protocol' is equal 'HTTP'", Value: nil, VulnLines: &[]model.CodeLine{}, }, { FileName: positive, - Line: 35, - IssueType: "IncorrectValue", + Line: 30, + IssueType: "MissingAttribute", SearchKey: "aws_alb_listener[front_end].default_action.redirect", KeyExpectedValue: "'default_action.redirect.protocol' is equal 'HTTPS'", - KeyActualValue: "'default_action.redirect.protocol' is equal 'HTTP'", + KeyActualValue: "'default_action.redirect.protocol' is missing", Value: nil, VulnLines: &[]model.CodeLine{}, },