Skip to content

Commit

Permalink
Add missing applicability fields from json (#945)
Browse files Browse the repository at this point in the history
  • Loading branch information
sverdlov93 authored Sep 11, 2023
1 parent d1f16cf commit 3839f85
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 35 deletions.
2 changes: 1 addition & 1 deletion xray/formats/simplejsonapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ type CveRow struct {
}

type Applicability struct {
Status bool `json:"status"`
Status string `json:"status"`
ScannerDescription string `json:"scannerDescription,omitempty"`
Evidence []Evidence `json:"evidence,omitempty"`
}
Expand Down
10 changes: 7 additions & 3 deletions xray/utils/analyzermanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"os/exec"
"path"
"path/filepath"
"strings"

"github.com/jfrog/jfrog-cli-core/v2/utils/config"
"github.com/jfrog/jfrog-cli-core/v2/utils/coreutils"
Expand Down Expand Up @@ -94,7 +95,7 @@ type AnalyzerManager struct {

func (am *AnalyzerManager) Exec(configFile, scanCommand, workingDir string, serverDetails *config.ServerDetails) (err error) {
if err = SetAnalyzerManagerEnvVariables(serverDetails); err != nil {
return err
return
}
cmd := exec.Command(am.AnalyzerManagerFullPath, scanCommand, configFile, am.MultiScanId)
defer func() {
Expand All @@ -105,8 +106,11 @@ func (am *AnalyzerManager) Exec(configFile, scanCommand, workingDir string, serv
}
}()
cmd.Dir = workingDir
err = cmd.Run()
return errorutils.CheckError(err)
output, err := cmd.CombinedOutput()
if err != nil {
err = errorutils.CheckErrorf("running %q in directory: %q failed: %s - %s", strings.Join(cmd.Args, " "), workingDir, err.Error(), string(output))
}
return
}

func GetAnalyzerManagerDownloadPath() (string, error) {
Expand Down
50 changes: 28 additions & 22 deletions xray/utils/resultstable.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,10 @@ func prepareViolations(violations []services.Violation, extendedResults *Extende
case "security":
cves := convertCves(violation.Cves)
applicableValue := getApplicableCveValue(extendedResults, cves)
for _, cve := range cves {
cve.Applicability = getCveApplicability(cve, extendedResults.ApplicabilityScanResults)
if extendedResults.EntitledForJas {
for i := range cves {
cves[i].Applicability = getCveApplicability(cves[i], extendedResults.ApplicabilityScanResults)
}
}
currSeverity := GetSeverity(violation.Severity, applicableValue)
jfrogResearchInfo := convertJfrogResearchInformation(violation.ExtendedInformation)
Expand Down Expand Up @@ -209,8 +211,10 @@ func prepareVulnerabilities(vulnerabilities []services.Vulnerability, extendedRe
}
cves := convertCves(vulnerability.Cves)
applicableValue := getApplicableCveValue(extendedResults, cves)
for _, cve := range cves {
cve.Applicability = getCveApplicability(cve, extendedResults.ApplicabilityScanResults)
if extendedResults.EntitledForJas {
for i := range cves {
cves[i].Applicability = getCveApplicability(cves[i], extendedResults.ApplicabilityScanResults)
}
}
currSeverity := GetSeverity(vulnerability.Severity, applicableValue)
jfrogResearchInfo := convertJfrogResearchInformation(vulnerability.ExtendedInformation)
Expand Down Expand Up @@ -910,7 +914,7 @@ func getApplicableCveValue(extendedResults *ExtendedScanResults, xrayCves []form
finalApplicableValue := NotApplicable
for _, applicabilityRun := range extendedResults.ApplicabilityScanResults {
for _, cve := range xrayCves {
relatedResults := GetResultsByRuleId(applicabilityRun, GetRuleIdFromCveId(cve.Id))
relatedResults := GetResultsByRuleId(applicabilityRun, CveToApplicabilityRuleId(cve.Id))
if len(relatedResults) == 0 {
finalApplicableValue = ApplicabilityUndetermined
}
Expand All @@ -928,37 +932,39 @@ func getApplicableCveValue(extendedResults *ExtendedScanResults, xrayCves []form
return ApplicabilityUndetermined
}

func getCveApplicability(cve formats.CveRow, applicabilityScanResults []*sarif.Run) (applicability *formats.Applicability) {
if len(applicabilityScanResults) == 0 {
return nil
}
func getCveApplicability(cve formats.CveRow, applicabilityScanResults []*sarif.Run) *formats.Applicability {
applicability := &formats.Applicability{Status: string(ApplicabilityUndetermined)}
for _, applicabilityRun := range applicabilityScanResults {
description := ""
if relatedRule, _ := applicabilityRun.GetRuleById(GetRuleIdFromCveId(cve.Id)); relatedRule != nil {
description = GetRuleFullDescription(relatedRule)
}
relatedResult, _ := applicabilityRun.GetResultByRuleId(GetRuleIdFromCveId(cve.Id))
if relatedResult == nil {
foundResult, _ := applicabilityRun.GetResultByRuleId(CveToApplicabilityRuleId(cve.Id))
if foundResult == nil {
continue
}
// Set applicable details
applicability = &formats.Applicability{
Status: isApplicableResult(relatedResult),
ScannerDescription: description,
applicability = &formats.Applicability{}
if isApplicableResult(foundResult) {
applicability.Status = string(Applicable)
} else {
applicability.Status = string(NotApplicable)
}

foundRule, _ := applicabilityRun.GetRuleById(CveToApplicabilityRuleId(cve.Id))
if foundRule != nil {
applicability.ScannerDescription = GetRuleFullDescription(foundRule)
}

// Add new evidences from locations
for _, location := range relatedResult.Locations {
for _, location := range foundResult.Locations {
applicability.Evidence = append(applicability.Evidence, formats.Evidence{
SourceCodeLocationRow: formats.SourceCodeLocationRow{
File: GetLocationFileName(location),
LineColumn: GetStartLocationInFile(location),
Snippet: GetLocationSnippet(location),
},
Reason: GetResultMsgText(relatedResult),
Reason: GetResultMsgText(foundResult),
})
}
break
}
return
return applicability
}

func printApplicableCveValue(applicableValue ApplicabilityStatus, isTable bool) string {
Expand Down
8 changes: 4 additions & 4 deletions xray/utils/resultstable_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ func TestGetApplicableCveValue(t *testing.T) {
},
cves: []services.Cve{{Id: "testCve2"}},
expectedResult: Applicable,
expectedCves: []formats.CveRow{{Id: "testCve2", Applicability: &formats.Applicability{Status: true}}},
expectedCves: []formats.CveRow{{Id: "testCve2", Applicability: &formats.Applicability{Status: string(Applicable)}}},
},
{
scanResults: &ExtendedScanResults{
Expand Down Expand Up @@ -490,7 +490,7 @@ func TestGetApplicableCveValue(t *testing.T) {
},
cves: []services.Cve{{Id: "testCve1"}, {Id: "testCve2"}},
expectedResult: NotApplicable,
expectedCves: []formats.CveRow{{Id: "testCve1", Applicability: &formats.Applicability{Status: false}}, {Id: "testCve2", Applicability: &formats.Applicability{Status: false}}},
expectedCves: []formats.CveRow{{Id: "testCve1", Applicability: &formats.Applicability{Status: string(NotApplicable)}}, {Id: "testCve2", Applicability: &formats.Applicability{Status: string(NotApplicable)}}},
},
{
scanResults: &ExtendedScanResults{
Expand All @@ -504,7 +504,7 @@ func TestGetApplicableCveValue(t *testing.T) {
},
cves: []services.Cve{{Id: "testCve1"}, {Id: "testCve2"}},
expectedResult: Applicable,
expectedCves: []formats.CveRow{{Id: "testCve1", Applicability: &formats.Applicability{Status: false}}, {Id: "testCve2", Applicability: &formats.Applicability{Status: true}}},
expectedCves: []formats.CveRow{{Id: "testCve1", Applicability: &formats.Applicability{Status: string(NotApplicable)}}, {Id: "testCve2", Applicability: &formats.Applicability{Status: string(Applicable)}}},
},
{
scanResults: &ExtendedScanResults{
Expand All @@ -514,7 +514,7 @@ func TestGetApplicableCveValue(t *testing.T) {
EntitledForJas: true},
cves: []services.Cve{{Id: "testCve1"}, {Id: "testCve2"}},
expectedResult: ApplicabilityUndetermined,
expectedCves: []formats.CveRow{{Id: "testCve1", Applicability: &formats.Applicability{Status: false}}, {Id: "testCve2"}},
expectedCves: []formats.CveRow{{Id: "testCve1", Applicability: &formats.Applicability{Status: string(NotApplicable)}}, {Id: "testCve2"}},
},
}

Expand Down
12 changes: 7 additions & 5 deletions xray/utils/sarifutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ const (
noneLevel SarifLevel = "none"

SeverityDefaultValue = "Medium"

applicabilityRuleIdPrefix = "applic_"
)

var (
Expand Down Expand Up @@ -137,7 +139,7 @@ func GetDiffFromResult(result *sarif.Result, source *sarif.Result) *sarif.Result
for _, targetCodeFlow := range GetLocationRelatedCodeFlowsFromResult(targetLocation, result) {
for _, sourceCodeFlow := range GetLocationRelatedCodeFlowsFromResult(targetLocation, source) {
if !IsSameCodeFlow(targetCodeFlow, sourceCodeFlow) {
// Code flow does not exists at source, add it and it's related location
// Code flow does not exist at source, add it and it's related location
newLocations.Add(targetLocation)
newCodeFlows = append(newCodeFlows, targetCodeFlow)
}
Expand Down Expand Up @@ -372,12 +374,12 @@ func GetRuleFullDescription(rule *sarif.ReportingDescriptor) string {
return ""
}

func GetRuleIdFromCveId(cveId string) string {
return "applic_" + cveId
func CveToApplicabilityRuleId(cveId string) string {
return applicabilityRuleIdPrefix + cveId
}

func GetCveIdFromRuleId(sarifRuleId string) string {
return strings.TrimPrefix(sarifRuleId, "applic_")
func ApplicabilityRuleIdToCve(sarifRuleId string) string {
return strings.TrimPrefix(sarifRuleId, applicabilityRuleIdPrefix)
}

func GetRunRules(run *sarif.Run) []*sarif.ReportingDescriptor {
Expand Down

0 comments on commit 3839f85

Please sign in to comment.