mirror of
https://github.com/SAP/jenkins-library.git
synced 2025-01-18 05:18:24 +02:00
feat(checkmarxExecuteScan): improvements to SARIF file generation (#3781)
* feat(checkmarxExecuteScan): respect SARIF standard more closely * fix(checkmarxExecuteScan): edge case where message would be empty in SARIF * fix(checkmarxExecuteScan): better message handling to ensure field is populated * feat(checkmarxExecuteScan): SARIF file readability * feat(checkmarxExecuteScan): include the helpURL as part of the Help object * fix(sarif): remove wrong structure addition * feat(checkmarxExecuteScan): safer handling of version in SARIF file * feat(checkmarxExecuteScan): add CWE number to tags
This commit is contained in:
parent
1d850c0acc
commit
1fde2ce677
@ -149,7 +149,7 @@ func Parse(data []byte) (format.SARIF, error) {
|
||||
checkmarxRun.ColumnKind = "utf16CodeUnits"
|
||||
sarif.Runs = append(sarif.Runs, checkmarxRun)
|
||||
rulesArray := []format.SarifRule{}
|
||||
baseURL := "https://" + strings.Split(cxxml.DeepLink, "/")[2] + "CxWebClient/ScanQueryDescription.aspx?"
|
||||
baseURL := "https://" + strings.Split(cxxml.DeepLink, "/")[2] + "/CxWebClient/ScanQueryDescription.aspx?"
|
||||
cweIdsForTaxonomies := make(map[string]int) //use a map to avoid duplicates
|
||||
cweCounter := 0
|
||||
|
||||
@ -165,15 +165,18 @@ func Parse(data []byte) (format.SARIF, error) {
|
||||
result := *new(format.Results)
|
||||
|
||||
//General
|
||||
result.RuleID = cxxml.Query[i].ID
|
||||
result.RuleID = "checkmarx-" + cxxml.Query[i].ID
|
||||
result.RuleIndex = cweIdsForTaxonomies[cxxml.Query[i].CweID]
|
||||
result.Level = "none"
|
||||
msg := new(format.Message)
|
||||
msg.Text = cxxml.Query[i].Categories
|
||||
//msg.Text = cxxml.Query[i].Name + ": " + cxxml.Query[i].Categories
|
||||
msg.Text = cxxml.Query[i].Name
|
||||
result.Message = msg
|
||||
analysisTarget := new(format.ArtifactLocation)
|
||||
analysisTarget.URI = cxxml.Query[i].Result[j].FileName
|
||||
result.AnalysisTarget = analysisTarget
|
||||
//analysisTarget := new(format.ArtifactLocation)
|
||||
//analysisTarget.URI = cxxml.Query[i].Result[j].FileName
|
||||
//analysisTarget.Index = index
|
||||
|
||||
//result.AnalysisTarget = analysisTarget
|
||||
if cxxml.Query[i].Name != "" {
|
||||
msg := new(format.Message)
|
||||
msg.Text = cxxml.Query[i].Name
|
||||
@ -181,14 +184,32 @@ func Parse(data []byte) (format.SARIF, error) {
|
||||
//Locations
|
||||
for k := 0; k < len(cxxml.Query[i].Result[j].Path.PathNode); k++ {
|
||||
loc := *new(format.Location)
|
||||
/*index := 0
|
||||
//Check if that artifact has been added
|
||||
added := false
|
||||
for file := 0; file < len(sarif.Runs[0].Artifacts); file++ {
|
||||
if sarif.Runs[0].Artifacts[file].Location.Uri == cxxml.Query[i].Result[j].FileName {
|
||||
added = true
|
||||
index = file
|
||||
break
|
||||
}
|
||||
}
|
||||
if !added {
|
||||
artifact := format.Artifact{Location: format.SarifLocation{Uri: cxxml.Query[i].Result[j].FileName}}
|
||||
sarif.Runs[0].Artifacts = append(sarif.Runs[0].Artifacts, artifact)
|
||||
index = len(sarif.Runs[0].Artifacts) - 1
|
||||
}
|
||||
loc.PhysicalLocation.ArtifactLocation.Index = index */
|
||||
loc.PhysicalLocation.ArtifactLocation.URI = cxxml.Query[i].Result[j].FileName
|
||||
loc.PhysicalLocation.Region.StartLine = cxxml.Query[i].Result[j].Path.PathNode[k].Line
|
||||
loc.PhysicalLocation.Region.EndLine = cxxml.Query[i].Result[j].Path.PathNode[k].Line
|
||||
loc.PhysicalLocation.Region.StartColumn = cxxml.Query[i].Result[j].Path.PathNode[k].Column
|
||||
snip := new(format.SnippetSarif)
|
||||
snip.Text = cxxml.Query[i].Result[j].Path.PathNode[k].Snippet.Line.Code
|
||||
loc.PhysicalLocation.Region.Snippet = snip
|
||||
loc.PhysicalLocation.ContextRegion.StartLine = cxxml.Query[i].Result[j].Path.PathNode[k].Line
|
||||
loc.PhysicalLocation.ContextRegion.EndLine = cxxml.Query[i].Result[j].Path.PathNode[k].Line
|
||||
loc.PhysicalLocation.ContextRegion.Snippet = snip
|
||||
//loc.PhysicalLocation.ContextRegion.StartLine = cxxml.Query[i].Result[j].Path.PathNode[k].Line
|
||||
//loc.PhysicalLocation.ContextRegion.EndLine = cxxml.Query[i].Result[j].Path.PathNode[k].Line
|
||||
//loc.PhysicalLocation.ContextRegion.Snippet = snip
|
||||
result.Locations = append(result.Locations, loc)
|
||||
|
||||
//Related Locations
|
||||
@ -203,6 +224,9 @@ func Parse(data []byte) (format.SARIF, error) {
|
||||
|
||||
}
|
||||
|
||||
result.PartialFingerprints.CheckmarxSimilarityID = cxxml.Query[i].Result[j].Path.SimilarityID
|
||||
result.PartialFingerprints.PrimaryLocationLineHash = cxxml.Query[i].Result[j].Path.SimilarityID
|
||||
|
||||
//Properties
|
||||
props := new(format.SarifProperties)
|
||||
props.Audited = false
|
||||
@ -258,9 +282,25 @@ func Parse(data []byte) (format.SARIF, error) {
|
||||
|
||||
//handle the rules array
|
||||
rule := *new(format.SarifRule)
|
||||
rule.ID = cxxml.Query[i].ID
|
||||
rule.Name = cxxml.Query[i].Name
|
||||
rule.ID = "checkmarx-" + cxxml.Query[i].ID
|
||||
words := strings.Split(cxxml.Query[i].Name, "_")
|
||||
for w := 0; w < len(words); w++ {
|
||||
words[w] = strings.Title(strings.ToLower(words[w]))
|
||||
}
|
||||
rule.Name = strings.Join(words, "")
|
||||
rule.HelpURI = baseURL + "queryID=" + cxxml.Query[i].ID + "&queryVersionCode=" + cxxml.Query[i].QueryVersionCode + "&queryTitle=" + cxxml.Query[i].Name
|
||||
rule.Help = new(format.Help)
|
||||
rule.Help.Text = rule.HelpURI
|
||||
rule.ShortDescription = new(format.Message)
|
||||
rule.ShortDescription.Text = cxxml.Query[i].Name
|
||||
if cxxml.Query[i].Categories != "" {
|
||||
rule.FullDescription = new(format.Message)
|
||||
rule.FullDescription.Text = cxxml.Query[i].Categories
|
||||
}
|
||||
rule.Properties = new(format.SarifRuleProperties)
|
||||
if cxxml.Query[i].CweID != "" {
|
||||
rule.Properties.Tags = append(rule.Properties.Tags, "external/cwe/cwe-"+cxxml.Query[i].CweID)
|
||||
}
|
||||
rulesArray = append(rulesArray, rule)
|
||||
}
|
||||
|
||||
@ -269,7 +309,13 @@ func Parse(data []byte) (format.SARIF, error) {
|
||||
tool := *new(format.Tool)
|
||||
tool.Driver = *new(format.Driver)
|
||||
tool.Driver.Name = "Checkmarx SCA"
|
||||
tool.Driver.Version = cxxml.CheckmarxVersion
|
||||
versionData := strings.Split(cxxml.CheckmarxVersion, "V ")
|
||||
if len(versionData) > 1 { // Safety check
|
||||
tool.Driver.Version = strings.Split(cxxml.CheckmarxVersion, "V ")[1]
|
||||
} else {
|
||||
tool.Driver.Version = cxxml.CheckmarxVersion // Safe case
|
||||
}
|
||||
tool.Driver.InformationUri = "https://checkmarx.atlassian.net/wiki/spaces/KC/pages/1170245301/Navigating+Scan+Results+v9.0.0+to+v9.2.0"
|
||||
tool.Driver.Rules = rulesArray
|
||||
sarif.Runs[0].Tool = tool
|
||||
|
||||
|
@ -11,7 +11,7 @@ func TestParse(t *testing.T) {
|
||||
//Use a test CXXML doc
|
||||
testCxxml := `
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<CxXMLResults InitiatorName="Test" Owner="Tester" ScanId="1111111" ProjectId="11037" ProjectName="test-project" TeamFullPathOnReportDate="CxServer" DeepLink="https://cxtext.test/CxWebClient/ViewerMain.aspx?scanid=1111111&projectid=11037" ScanStart="Monday, March 7, 2022 1:58:49 PM" Preset="Checkmarx Default" ScanTime="00h:00m:22s" LinesOfCodeScanned="2682" FilesScanned="15" ReportCreationTime="Monday, March 7, 2022 1:59:25 PM" Team="SecurityTesting" CheckmarxVersion="9.4.3" ScanComments="Scan From Golang Script" ScanType="Incremental" SourceOrigin="LocalPath" Visibility="Public">
|
||||
<CxXMLResults InitiatorName="Test" Owner="Tester" ScanId="1111111" ProjectId="11037" ProjectName="test-project" TeamFullPathOnReportDate="CxServer" DeepLink="https://cxtext.test/CxWebClient/ViewerMain.aspx?scanid=1111111&projectid=11037" ScanStart="Monday, March 7, 2022 1:58:49 PM" Preset="Checkmarx Default" ScanTime="00h:00m:22s" LinesOfCodeScanned="2682" FilesScanned="15" ReportCreationTime="Monday, March 7, 2022 1:59:25 PM" Team="SecurityTesting" CheckmarxVersion="V 9.4.3" ScanComments="Scan From Golang Script" ScanType="Incremental" SourceOrigin="LocalPath" Visibility="Public">
|
||||
<Query id="2415" categories="Dummy Categories" cweId="79" name="Dummy Vuln 1" group="JavaScript_High_Risk" Severity="High" Language="JavaScript" LanguageHash="9095271965336651" LanguageChangeDate="2022-01-16T00:00:00.0000000" SeverityIndex="3" QueryPath="JavaScript\Cx\JavaScript High Risk\Dummy Vuln 1:4" QueryVersionCode="14383421">
|
||||
<Result NodeId="143834211111" FileName="test/any.ts" Status="Recurrent" Line="7" Column="46" FalsePositive="False" Severity="High" AssignToUser="" state="0" Remark="" DeepLink="https://cxtext.test/CxWebClient/ViewerMain.aspx?" SeverityIndex="3" StatusIndex="1" DetectionDate="3/7/2022 12:21:30 PM">
|
||||
<Path ResultId="11037" PathId="4" SimilarityId="-1754124988" SourceMethod="function" DestinationMethod="function">
|
||||
|
@ -56,8 +56,8 @@ type PhysicalLocation struct {
|
||||
// ArtifactLocation describing the path of the artifact
|
||||
type ArtifactLocation struct {
|
||||
URI string `json:"uri"`
|
||||
URIBaseId string `json:"uriBaseId"`
|
||||
Index int `json:"index"`
|
||||
URIBaseId string `json:"uriBaseId,omitempty"`
|
||||
Index int `json:"index,omitempty"`
|
||||
}
|
||||
|
||||
// Region where the finding was detected
|
||||
@ -265,9 +265,9 @@ type SrcRoot struct {
|
||||
// Artifact These structs are relevant to the artifacts object
|
||||
type Artifact struct {
|
||||
Location SarifLocation `json:"location"`
|
||||
Length int `json:"length"`
|
||||
MimeType string `json:"mimeType"`
|
||||
Encoding string `json:"encoding"`
|
||||
Length int `json:"length,omitempty"`
|
||||
MimeType string `json:"mimeType,omitempty"`
|
||||
Encoding string `json:"encoding,omitempty"`
|
||||
}
|
||||
|
||||
// SarifLocation
|
||||
|
Loading…
x
Reference in New Issue
Block a user