Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add missing applicability fields from json #945

Merged
merged 6 commits into from
Sep 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading