Classify Fortify & Checkmarx findings into audit group / Common properties (#3904)

* fix(fortify): suppressed issues got "Unknown" category and state

* fix (fortify-sarif): classify findings into audit group

* fix(fortify-checkmarx-sarif): common properties bag for Fortify and Checkmarx (accepting the risk of empty value)

* fix (checkmarx-sarif): classify findings into audit group

* fix (sarif): formatting
This commit is contained in:
thtri
2022-07-21 11:15:55 +02:00
committed by GitHub
parent f6a6448631
commit ef3e720464
5 changed files with 62 additions and 4 deletions
+15
View File
@@ -260,6 +260,21 @@ func Parse(sys System, data []byte, scanID int) (format.SARIF, error) {
props.InstanceID = cxxml.Query[i].Result[j].Path.ResultID + "-" + strconv.Itoa(cxxml.Query[i].Result[j].Path.PathID)
props.ToolSeverity = cxxml.Query[i].Result[j].Severity
props.ToolSeverityIndex = cxxml.Query[i].Result[j].SeverityIndex
// classify into audit groups
switch cxxml.Query[i].Result[j].Severity {
case "High", "Medium":
props.AuditRequirement = format.AUDIT_REQUIREMENT_GROUP_1_DESC
props.AuditRequirementIndex = format.AUDIT_REQUIREMENT_GROUP_1_INDEX
break
case "Low":
props.AuditRequirement = format.AUDIT_REQUIREMENT_GROUP_2_DESC
props.AuditRequirementIndex = format.AUDIT_REQUIREMENT_GROUP_2_INDEX
break
case "Information":
props.AuditRequirement = format.AUDIT_REQUIREMENT_GROUP_3_DESC
props.AuditRequirementIndex = format.AUDIT_REQUIREMENT_GROUP_3_INDEX
break
}
props.ToolStateIndex = cxxml.Query[i].Result[j].State
switch cxxml.Query[i].Result[j].State {
case 1:
+10
View File
@@ -3,6 +3,7 @@ package checkmarx
import (
"testing"
"github.com/SAP/jenkins-library/pkg/format"
piperHttp "github.com/SAP/jenkins-library/pkg/http"
"github.com/SAP/jenkins-library/pkg/log"
"github.com/stretchr/testify/assert"
@@ -121,7 +122,16 @@ func TestParse(t *testing.T) {
assert.Equal(t, len(sarif.Runs[0].Tool.Driver.Rules), 2)
assert.Equal(t, sarif.Runs[0].Results[2].Properties.ToolState, "Confirmed")
assert.Equal(t, sarif.Runs[0].Results[2].Properties.ToolAuditMessage, "Changed status to Confirmed \n Dummy comment")
assert.Equal(t, sarif.Runs[0].Results[2].Properties.ToolSeverityIndex, 3)
assert.Equal(t, sarif.Runs[0].Results[2].Properties.ToolSeverity, "High")
assert.Equal(t, sarif.Runs[0].Results[2].Properties.AuditRequirementIndex, format.AUDIT_REQUIREMENT_GROUP_1_INDEX)
assert.Equal(t, sarif.Runs[0].Results[2].Properties.AuditRequirement, format.AUDIT_REQUIREMENT_GROUP_1_DESC)
//assert.Equal(t, "This is a dummy short description.", sarif.Runs[0].Tool.Driver.Rules[0].FullDescription.Text)
// ensure the existence of not applicable field (specific Fortify)
assert.Equal(t, sarif.Runs[0].Results[2].Properties.InstanceSeverity, "")
assert.Equal(t, sarif.Runs[0].Results[2].Properties.Confidence, "")
assert.Equal(t, sarif.Runs[0].Results[2].Properties.FortifyCategory, "")
})
t.Run("Missing sys", func(t *testing.T) {
+16 -4
View File
@@ -1,5 +1,12 @@
package format
const AUDIT_REQUIREMENT_GROUP_1_INDEX = 1
const AUDIT_REQUIREMENT_GROUP_2_INDEX = 2
const AUDIT_REQUIREMENT_GROUP_3_INDEX = 3
const AUDIT_REQUIREMENT_GROUP_1_DESC = "Audit All"
const AUDIT_REQUIREMENT_GROUP_2_DESC = "Spot Check"
const AUDIT_REQUIREMENT_GROUP_3_DESC = "Optional"
// SARIF format related JSON structs
type SARIF struct {
Schema string `json:"$schema" default:"https://docs.oasis-open.org/sarif/sarif/v2.1.0/cos02/schemas/sarif-schema-2.1.0.json"`
@@ -87,12 +94,9 @@ type PartialFingerprints struct {
// SarifProperties adding additional information/context to the finding
type SarifProperties struct {
// common
RuleGUID string `json:"ruleGUID,omitempty"`
InstanceID string `json:"instanceID,omitempty"`
InstanceSeverity string `json:"instanceSeverity,omitempty"`
Confidence string `json:"confidence,omitempty"`
FortifyCategory string `json:"fortifyCategory,omitempty"`
CheckmarxSimilarityID string `json:"checkmarxSimilarityID,omitempty"`
Audited bool `json:"audited"`
ToolSeverity string `json:"toolSeverity"`
ToolSeverityIndex int `json:"toolSeverityIndex"`
@@ -100,6 +104,14 @@ type SarifProperties struct {
ToolStateIndex int `json:"toolStateIndex"`
ToolAuditMessage string `json:"toolAuditMessage"`
UnifiedAuditState string `json:"unifiedAuditState"`
AuditRequirement string `json:"auditRequirement"`
AuditRequirementIndex int `json:"auditRequirementIndex"`
// specific
InstanceSeverity string `json:"instanceSeverity"`
Confidence string `json:"confidence"`
FortifyCategory string `json:"fortifyCategory"`
CheckmarxSimilarityID string `json:"checkmarxSimilarityID"`
}
// Tool these structs are relevant to the Tool object
+15
View File
@@ -1189,6 +1189,9 @@ func integrateAuditData(ruleProp *format.SarifProperties, issueInstanceID string
ruleProp.ToolAuditMessage = "Error fetching audit state" // We set this as default for the error phase, then reset it to nothing
ruleProp.ToolSeverityIndex = 0
ruleProp.ToolStateIndex = 0
ruleProp.AuditRequirementIndex = 0
ruleProp.AuditRequirement = "Unknown"
// These default values allow for the property bag to be filled even if an error happens later. They all should be overwritten by a normal course of the progrma.
if maxretries == 0 {
// Max retries reached, we stop there to avoid a longer execution time
@@ -1231,6 +1234,18 @@ func integrateAuditData(ruleProp *format.SarifProperties, issueInstanceID string
for i := 0; i < len(filterSet.Folders); i++ {
if filterSet.Folders[i].GUID == *data[0].FolderGUID {
ruleProp.FortifyCategory = filterSet.Folders[i].Name
// classify into audit groups
switch ruleProp.FortifyCategory {
case "Corporate Security Requirements", "Audit All":
ruleProp.AuditRequirementIndex = format.AUDIT_REQUIREMENT_GROUP_1_INDEX
ruleProp.AuditRequirement = format.AUDIT_REQUIREMENT_GROUP_1_DESC
case "Spot Checks of Each Category":
ruleProp.AuditRequirementIndex = format.AUDIT_REQUIREMENT_GROUP_2_INDEX
ruleProp.AuditRequirement = format.AUDIT_REQUIREMENT_GROUP_2_DESC
case "Optional":
ruleProp.AuditRequirementIndex = format.AUDIT_REQUIREMENT_GROUP_3_INDEX
ruleProp.AuditRequirement = format.AUDIT_REQUIREMENT_GROUP_3_DESC
}
break
}
}
+6
View File
@@ -446,6 +446,9 @@ func TestIntegrateAuditData(t *testing.T) {
assert.Equal(t, ruleProp.ToolSeverityIndex, 3)
assert.Equal(t, ruleProp.ToolAuditMessage, "Dummy comment.")
assert.Equal(t, ruleProp.FortifyCategory, "Audit All")
assert.Equal(t, ruleProp.AuditRequirementIndex, format.AUDIT_REQUIREMENT_GROUP_1_INDEX)
assert.Equal(t, ruleProp.AuditRequirement, format.AUDIT_REQUIREMENT_GROUP_1_DESC)
assert.Equal(t, ruleProp.CheckmarxSimilarityID, "") // ensure the existence of not applicable field (specific Checkmarx)
})
t.Run("Missing project version", func(t *testing.T) {
@@ -490,6 +493,9 @@ func TestIntegrateAuditData(t *testing.T) {
assert.Equal(t, ruleProp.ToolSeverityIndex, 3)
assert.Equal(t, ruleProp.ToolAuditMessage, "Dummy comment.")
assert.Equal(t, ruleProp.FortifyCategory, "Audit All")
assert.Equal(t, ruleProp.AuditRequirementIndex, format.AUDIT_REQUIREMENT_GROUP_1_INDEX)
assert.Equal(t, ruleProp.AuditRequirement, format.AUDIT_REQUIREMENT_GROUP_1_DESC)
assert.Equal(t, ruleProp.CheckmarxSimilarityID, "") // ensure the existence of not applicable field (specific Checkmarx)
})
t.Run("Max retries set to 0: error raised", func(t *testing.T) {