mirror of
https://github.com/SAP/jenkins-library.git
synced 2026-06-19 22:58:55 +02:00
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:
@@ -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:
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user