1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2025-03-03 15:02:35 +02:00

feat(checkmarxExecuteScan): convert Checkmarx xml report to SARIF (#3696)

* feat(checkmarxExecuteScan): sarif conversion for Checkmarx XML reports

* feat(checkmarxExecuteScan): added taxonomies and similarityID

* fix(checkmarxExecuteScan): proper handling of ruleId and ruleIndex

* fix(sarif): mistype in checkmarx properties

* fix(checkmarxExecuteScan): fixed occasional panics when handling audit comment

* chore(sarif): proper variable naming

* chore(code): fix missing and unrecognized comments

* trigger PR

* fix(format): extra space

Co-authored-by: Sven Merk <33895725+nevskrem@users.noreply.github.com>
This commit is contained in:
xgoffin 2022-04-04 16:12:35 +02:00 committed by GitHub
parent 6b6208a35c
commit 3c55d3c99c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 490 additions and 13 deletions

View File

@ -322,6 +322,20 @@ func verifyCxProjectCompliance(config checkmarxExecuteScanOptions, sys checkmarx
}
reports = append(reports, piperutils.Path{Target: xmlReportName})
// generate sarif report
if config.ConvertToSarif {
log.Entry().Info("Calling conversion to SARIF function.")
sarif, err := checkmarx.ConvertCxxmlToSarif(xmlReportName)
if err != nil {
return fmt.Errorf("failed to generate SARIF")
}
paths, err := checkmarx.WriteSarif(sarif)
if err != nil {
return fmt.Errorf("failed to write sarif")
}
reports = append(reports, paths...)
}
// create toolrecord
toolRecordFileName, err := createToolRecordCx(utils.GetWorkspace(), config, results)
if err != nil {

View File

@ -52,6 +52,7 @@ type checkmarxExecuteScanOptions struct {
VulnerabilityThresholdUnit string `json:"vulnerabilityThresholdUnit,omitempty"`
IsOptimizedAndScheduled bool `json:"isOptimizedAndScheduled,omitempty"`
CreateResultIssue bool `json:"createResultIssue,omitempty"`
ConvertToSarif bool `json:"convertToSarif,omitempty"`
}
type checkmarxExecuteScanInflux struct {
@ -356,6 +357,7 @@ func addCheckmarxExecuteScanFlags(cmd *cobra.Command, stepConfig *checkmarxExecu
cmd.Flags().StringVar(&stepConfig.VulnerabilityThresholdUnit, "vulnerabilityThresholdUnit", `percentage`, "The unit for the threshold to apply.")
cmd.Flags().BoolVar(&stepConfig.IsOptimizedAndScheduled, "isOptimizedAndScheduled", false, "Whether the pipeline runs in optimized mode and the current execution is a scheduled one")
cmd.Flags().BoolVar(&stepConfig.CreateResultIssue, "createResultIssue", false, "Activate creation of a result issue in GitHub.")
cmd.Flags().BoolVar(&stepConfig.ConvertToSarif, "convertToSarif", false, "[BETA] Convert the Checkmarx XML (Cxxml) scan results to the open SARIF standard. Uploaded through Cumulus later on.")
cmd.MarkFlagRequired("password")
cmd.MarkFlagRequired("projectName")
@ -705,6 +707,15 @@ func checkmarxExecuteScanMetadata() config.StepData {
Aliases: []config.Alias{},
Default: false,
},
{
Name: "convertToSarif",
ResourceRef: []config.ResourceReference{},
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
Type: "bool",
Mandatory: false,
Aliases: []config.Alias{},
Default: false,
},
},
},
Outputs: config.StepOutputs{

View File

@ -0,0 +1,290 @@
package checkmarx
import (
"bytes"
"encoding/xml"
"io/ioutil"
"strconv"
"strings"
"github.com/SAP/jenkins-library/pkg/format"
"github.com/SAP/jenkins-library/pkg/log"
"github.com/pkg/errors"
)
// CxXMLResults : This struct encapsulates everyting in the Cx XML document
type CxXMLResults struct {
XMLName xml.Name `xml:"CxXMLResults"`
InitiatorName string `xml:"InitiatorName,attr"`
Owner string `xml:"Owner,attr"`
ScanID string `xml:"ScanId,attr"`
ProjectID string `xml:"ProjectId,attr"`
ProjectName string `xml:"ProjectName,attr"`
TeamFullPathOnReportDate string `xml:"TeamFullPathOnReportDate,attr"`
DeepLink string `xml:"DeepLink,attr"`
ScanStart string `xml:"ScanStart,attr"`
Preset string `xml:"Preset,attr"`
ScanTime string `xml:"ScanTime,attr"`
LinesOfCodeScanned string `xml:"LinesOfCodeScanned,attr"`
FilesScanned string `xml:"FilesScanned,attr"`
ReportCreationTime string `xml:"ReportCreationTime,attr"`
Team string `xml:"Team,attr"`
CheckmarxVersion string `xml:"CheckmarxVersion,attr"`
ScanComments string `xml:"ScanComments,attr"`
ScanType string `xml:"ScanType,attr"`
SourceOrigin string `xml:"SourceOrigin,attr"`
Visibility string `xml:"Visibility,attr"`
Query []CxxmlQuery `xml:"Query"`
}
// CxxmlQuery CxxmlQuery
type CxxmlQuery struct {
XMLName xml.Name `xml:"Query"`
ID string `xml:"id,attr"`
Categories string `xml:"categories,attr"`
CweID string `xml:"cweId,attr"`
Name string `xml:"name,attr"`
Group string `xml:"group,attr"`
Severity string `xml:"Severity,attr"`
Language string `xml:"Language,attr"`
LanguageHash string `xml:"LanguageHash,attr"`
LanguageChangeDate string `xml:"LanguageChangeDate,attr"`
SeverityIndex int `xml:"SeverityIndex,attr"`
QueryPath string `xml:"QueryPath,attr"`
QueryVersionCode string `xml:"QueryVersionCode,attr"`
Result []CxxmlResult `xml:"Result"`
}
// CxxmlResult CxxmlResult
type CxxmlResult struct {
XMLName xml.Name `xml:"Result"`
NodeID string `xml:"NodeId,attr"`
FileName string `xml:"FileName,attr"`
Status string `xml:"Status,attr"`
Line int `xml:"Line,attr"`
Column int `xml:"Column,attr"`
FalsePositive bool `xml:"FalsePositive,attr"`
Severity string `xml:"Severity,attr"`
AssignToUser string `xml:"AssignToUser,attr"`
State int `xml:"state,attr"`
Remark string `xml:"Remark,attr"`
DeepLink string `xml:"DeepLink,attr"`
SeverityIndex int `xml:"SeverityIndex,attr"`
StatusIndex int `xml:"StatusIndex,attr"`
DetectionDate string `xml:"DetectionDate,attr"`
Path Path `xml:"Path"`
}
// Path Path
type Path struct {
XMLName xml.Name `xml:"Path"`
ResultID string `xml:"ResultId,attr"`
PathID int `xml:"PathId,attr"`
SimilarityID string `xml:"SimilarityId,attr"`
SourceMethod string `xml:"SourceMethod,attr"`
DestinationMethod string `xml:"DestinationMethod,attr"`
PathNode []PathNode `xml:"PathNode"`
}
// PathNode PathNode
type PathNode struct {
XMLName xml.Name `xml:"PathNode"`
FileName string `xml:"FileName"`
Line int `xml:"Line"`
Column int `xml:"Column"`
NodeID int `xml:"NodeId"`
Name string `xml:"Name"`
Type string `xml:"Type"`
Length int `xml:"Length"`
Snippet Snippet `xml:"Snippet"`
}
// Snippet Snippet
type Snippet struct {
XMLName xml.Name `xml:"Snippet"`
Line Line `xml:"Line"`
}
// Line Line
type Line struct {
XMLName xml.Name `xml:"Line"`
Number int `xml:"Number"`
Code string `xml:"Code"`
}
// ConvertCxxmlToSarif is the entrypoint for the Parse function
func ConvertCxxmlToSarif(xmlReportName string) (format.SARIF, error) {
var sarif format.SARIF
data, err := ioutil.ReadFile(xmlReportName)
if err != nil {
return sarif, err
}
if len(data) == 0 {
log.Entry().Error("Error reading audit file at " + xmlReportName + ". This might be that the file is missing, corrupted, or too large. Aborting procedure.")
err := errors.New("cannot read audit file")
return sarif, err
}
log.Entry().Debug("Calling Parse.")
return Parse(data)
}
// Parse function
func Parse(data []byte) (format.SARIF, error) {
reader := bytes.NewReader(data)
decoder := xml.NewDecoder(reader)
var cxxml CxXMLResults
err := decoder.Decode(&cxxml)
if err != nil {
return format.SARIF{}, err
}
// Process sarif
var sarif format.SARIF
sarif.Schema = "https://docs.oasis-open.org/sarif/sarif/v2.1.0/cos02/schemas/sarif-schema-2.1.0.json"
sarif.Version = "2.1.0"
var checkmarxRun format.Runs
checkmarxRun.ColumnKind = "utf16CodeUnits"
sarif.Runs = append(sarif.Runs, checkmarxRun)
rulesArray := []format.SarifRule{}
baseURL := "https://" + strings.Split(cxxml.DeepLink, "/")[2] + "CxWebClient/ScanQueryDescription.aspx?"
cweIdsForTaxonomies := make(map[string]int) //use a map to avoid duplicates
cweCounter := 0
//CxXML files contain a CxXMLResults > Query object, which represents a broken rule or type of vuln
//This Query object contains a list of Result objects, each representing an occurence
//Each Result object contains a ResultPath, which represents the exact location of the occurence (the "Snippet")
for i := 0; i < len(cxxml.Query); i++ {
//add cweid to array
cweIdsForTaxonomies[cxxml.Query[i].CweID] = cweCounter
cweCounter = cweCounter + 1
for j := 0; j < len(cxxml.Query[i].Result); j++ {
result := *new(format.Results)
//General
result.RuleID = cxxml.Query[i].ID
result.RuleIndex = cweIdsForTaxonomies[cxxml.Query[i].CweID]
result.Level = "none"
msg := new(format.Message)
msg.Text = cxxml.Query[i].Categories
result.Message = msg
analysisTarget := new(format.ArtifactLocation)
analysisTarget.URI = cxxml.Query[i].Result[j].FileName
result.AnalysisTarget = analysisTarget
if cxxml.Query[i].Name != "" {
msg := new(format.Message)
msg.Text = cxxml.Query[i].Name
}
//Locations
for k := 0; k < len(cxxml.Query[i].Result[j].Path.PathNode); k++ {
loc := *new(format.Location)
loc.PhysicalLocation.ArtifactLocation.URI = cxxml.Query[i].Result[j].FileName
loc.PhysicalLocation.Region.StartLine = cxxml.Query[i].Result[j].Path.PathNode[k].Line
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
result.Locations = append(result.Locations, loc)
//Related Locations
relatedLocation := *new(format.RelatedLocation)
relatedLocation.ID = k + 1
relatedLocation.PhysicalLocation = *new(format.RelatedPhysicalLocation)
relatedLocation.PhysicalLocation.ArtifactLocation = loc.PhysicalLocation.ArtifactLocation
relatedLocation.PhysicalLocation.Region = *new(format.RelatedRegion)
relatedLocation.PhysicalLocation.Region.StartLine = loc.PhysicalLocation.Region.StartLine
relatedLocation.PhysicalLocation.Region.StartColumn = cxxml.Query[i].Result[j].Path.PathNode[k].Column
result.RelatedLocations = append(result.RelatedLocations, relatedLocation)
}
//Properties
props := new(format.SarifProperties)
props.Audited = false
if cxxml.Query[i].Result[j].Remark != "" {
props.Audited = true
}
props.CheckmarxSimilarityID = cxxml.Query[i].Result[j].Path.SimilarityID
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
props.ToolStateIndex = cxxml.Query[i].Result[j].State
switch cxxml.Query[i].Result[j].State {
case 1:
props.ToolState = "NotExploitable"
break
case 2:
props.ToolState = "Confirmed"
break
case 3:
props.ToolState = "Urgent"
break
case 4:
props.ToolState = "ProposedNotExploitable"
break
default:
props.ToolState = "ToVerify" // Includes case 0
break
}
props.ToolAuditMessage = ""
if cxxml.Query[i].Result[j].Remark != "" {
remarks := strings.Split(cxxml.Query[i].Result[j].Remark, "\n")
messageCandidates := []string{}
for cnd := 0; cnd < len(remarks); cnd++ {
candidate := strings.Split(remarks[cnd], "]: ")
if len(candidate) == 1 {
if len(candidate[0]) != 0 {
messageCandidates = append([]string{strings.Trim(candidate[0], "\r\n")}, messageCandidates...)
}
continue
} else if len(candidate) == 0 {
continue
}
messageCandidates = append([]string{strings.Trim(candidate[1], "\r\n")}, messageCandidates...) //Append in reverse order, trim to remove extra \r
}
props.ToolAuditMessage = strings.Join(messageCandidates, " \n ")
}
props.UnifiedAuditState = ""
result.Properties = props
//Finalize
sarif.Runs[0].Results = append(sarif.Runs[0].Results, result)
}
//handle the rules array
rule := *new(format.SarifRule)
rule.ID = cxxml.Query[i].ID
rule.Name = cxxml.Query[i].Name
rule.HelpURI = baseURL + "queryID=" + cxxml.Query[i].ID + "&queryVersionCode=" + cxxml.Query[i].QueryVersionCode + "&queryTitle=" + cxxml.Query[i].Name
rulesArray = append(rulesArray, rule)
}
// Handle driver object
tool := *new(format.Tool)
tool.Driver = *new(format.Driver)
tool.Driver.Name = "Checkmarx SCA"
tool.Driver.Version = cxxml.CheckmarxVersion
tool.Driver.Rules = rulesArray
sarif.Runs[0].Tool = tool
//handle automationDetails
sarif.Runs[0].AutomationDetails.Id = cxxml.DeepLink // Use deeplink to pass a maximum of information
//handle taxonomies
//Only one exists apparently: CWE. It is fixed
taxonomy := *new(format.Taxonomies)
taxonomy.Name = "CWE"
taxonomy.Organization = "MITRE"
taxonomy.ShortDescription.Text = "The MITRE Common Weakness Enumeration"
for key := range cweIdsForTaxonomies {
taxa := *new(format.Taxa)
taxa.Id = key
taxonomy.Taxa = append(taxonomy.Taxa, taxa)
}
sarif.Runs[0].Taxonomies = append(sarif.Runs[0].Taxonomies, taxonomy)
return sarif, nil
}

View File

@ -0,0 +1,123 @@
package checkmarx
import (
"testing"
"github.com/stretchr/testify/assert"
)
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&amp;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">
<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">
<PathNode>
<FileName>test/any.ts</FileName>
<Line>7</Line>
<Column>46</Column>
<NodeId>1</NodeId>
<Name>slice</Name>
<Type></Type>
<Length>5</Length>
<Snippet>
<Line>
<Number>7</Number>
<Code>dummy code</Code>
</Line>
</Snippet>
</PathNode>
<PathNode>
<FileName>test/any.ts</FileName>
<Line>7</Line>
<Column>12</Column>
<NodeId>2</NodeId>
<Name>location</Name>
<Type></Type>
<Length>8</Length>
<Snippet>
<Line>
<Number>7</Number>
<Code>dummy code 2</Code>
</Line>
</Snippet>
</PathNode>
</Path>
</Result>
<Result NodeId="143834211112" FileName="html/ts.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="4845356468" PathId="5" SimilarityId="-1465173916" SourceMethod="function" DestinationMethod="function">
<PathNode>
<FileName>html/other.ts</FileName>
<Line>7</Line>
<Column>46</Column>
<NodeId>1</NodeId>
<Name>slice</Name>
<Type></Type>
<Length>5</Length>
<Snippet>
<Line>
<Number>7</Number>
<Code>dummycode</Code>
</Line>
</Snippet>
</PathNode>
<PathNode>
<FileName>html/other.ts</FileName>
<Line>7</Line>
<Column>12</Column>
<NodeId>2</NodeId>
<Name>location</Name>
<Type></Type>
<Length>8</Length>
<Snippet>
<Line>
<Number>7</Number>
<Code>dummycode2</Code>
</Line>
</Snippet>
</PathNode>
</Path>
</Result>
</Query>
<Query id="1111" categories="Dummy Categories" cweId="79" name="Dummy Vuln 2" 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="2" Remark="Test-user Test-project, [Monday, March 7, 2022 1:57:26 PM]: Dummy comment&#xD;&#xA;Test-user Test-project, [Monday, March 7, 2022 1:57:26 PM]: Changed status to Confirmed" 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">
<PathNode>
<FileName>test/any.ts</FileName>
<Line>7</Line>
<Column>46</Column>
<NodeId>1</NodeId>
<Name>slice</Name>
<Type></Type>
<Length>5</Length>
<Snippet>
<Line>
<Number>7</Number>
<Code>dummy code</Code>
</Line>
</Snippet>
</PathNode>
</Path>
</Result>
</Query>
</CxXMLResults>
`
t.Run("Valid config", func(t *testing.T) {
sarif, err := Parse([]byte(testCxxml))
assert.NoError(t, err, "error")
assert.Equal(t, len(sarif.Runs[0].Results), 3)
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")
})
t.Run("Missing data", func(t *testing.T) {
_, err := Parse([]byte{})
assert.Error(t, err, "EOF")
})
}

View File

@ -1,6 +1,7 @@
package checkmarx
import (
"bytes"
"crypto/sha1"
"encoding/json"
"fmt"
@ -9,6 +10,7 @@ import (
"strings"
"time"
"github.com/SAP/jenkins-library/pkg/format"
"github.com/SAP/jenkins-library/pkg/log"
"github.com/SAP/jenkins-library/pkg/piperutils"
"github.com/SAP/jenkins-library/pkg/reporting"
@ -182,6 +184,35 @@ func WriteJSONReport(jsonReport CheckmarxReportData) ([]piperutils.Path, error)
return reportPaths, nil
}
// WriteSarif writes a json file to disk as a .sarif if it respects the specification declared in format.SARIF
func WriteSarif(sarif format.SARIF) ([]piperutils.Path, error) {
utils := piperutils.Files{}
reportPaths := []piperutils.Path{}
sarifReportPath := filepath.Join(ReportsDirectory, "result.sarif")
// Ensure reporting directory exists
if err := utils.MkdirAll(ReportsDirectory, 0777); err != nil {
return reportPaths, errors.Wrapf(err, "failed to create report directory")
}
// HTML characters will most likely be present: we need to use encode: create a buffer to hold JSON data
buffer := new(bytes.Buffer)
// create JSON encoder for buffer
bufEncoder := json.NewEncoder(buffer)
// set options
bufEncoder.SetEscapeHTML(false)
bufEncoder.SetIndent("", " ")
//encode to buffer
bufEncoder.Encode(sarif)
if err := utils.FileWrite(sarifReportPath, buffer.Bytes(), 0666); err != nil {
log.SetErrorCategory(log.ErrorConfiguration)
return reportPaths, errors.Wrapf(err, "failed to write Checkmarx SARIF report")
}
reportPaths = append(reportPaths, piperutils.Path{Name: "Checkmarx SARIF Report", Target: sarifReportPath})
return reportPaths, nil
}
func WriteCustomReports(scanReport reporting.ScanReport, projectName, projectID string) ([]piperutils.Path, error) {
utils := piperutils.Files{}
reportPaths := []piperutils.Path{}

View File

@ -76,17 +76,18 @@ type LogicalLocation struct {
// SarifProperties adding additional information/context to the finding
type SarifProperties struct {
InstanceID string `json:"instanceID,omitempty"`
InstanceSeverity string `json:"instanceSeverity,omitempty"`
Confidence string `json:"confidence,omitempty"`
FortifyCategory string `json:"fortifyCategory,omitempty"`
Audited bool `json:"audited"`
ToolSeverity string `json:"toolSeverity"`
ToolSeverityIndex int `json:"toolSeverityIndex"`
ToolState string `json:"toolState"`
ToolStateIndex int `json:"toolStateIndex"`
ToolAuditMessage string `json:"toolAuditMessage"`
UnifiedAuditState string `json:"unifiedAuditState"`
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"`
ToolState string `json:"toolState"`
ToolStateIndex int `json:"toolStateIndex"`
ToolAuditMessage string `json:"toolAuditMessage"`
UnifiedAuditState string `json:"unifiedAuditState"`
}
// Tool these structs are relevant to the Tool object
@ -275,7 +276,7 @@ type AutomationDetails struct {
// Taxonomies These structs are relevant to the taxonomies object
type Taxonomies struct {
Guid string `json:"guid"`
GUID string `json:"guid,omitempty"`
Name string `json:"name"`
Organization string `json:"organization"`
ShortDescription Message `json:"shortDescription"`

View File

@ -1015,7 +1015,7 @@ func Parse(sys System, project *models.Project, projectVersion *models.ProjectVe
//handle taxonomies
//Only one exists apparently: CWE. It is fixed
taxonomy := *new(format.Taxonomies)
taxonomy.Guid = "25F72D7E-8A92-459D-AD67-64853F788765"
taxonomy.GUID = "25F72D7E-8A92-459D-AD67-64853F788765"
taxonomy.Name = "CWE"
taxonomy.Organization = "MITRE"
taxonomy.ShortDescription.Text = "The MITRE Common Weakness Enumeration"

View File

@ -319,6 +319,13 @@ spec:
- STAGES
- STEPS
default: false
- name: convertToSarif
type: bool
description: "[BETA] Convert the Checkmarx XML (Cxxml) scan results to the open SARIF standard. Uploaded through Cumulus later on."
scope:
- PARAMETERS
- STAGES
- STEPS
outputs:
resources:
- name: influx