From 04432bfafde606cdf6cdc62df17ddf21d24a010e Mon Sep 17 00:00:00 2001 From: delarea Date: Wed, 13 Sep 2023 13:15:00 +0300 Subject: [PATCH] CR --- .../jas/applicability/applicabilitymanager.go | 39 +++++++-------- xray/commands/audit/jas/common.go | 4 +- xray/utils/resultstable.go | 50 ++++++++++--------- xray/utils/resultstable_test.go | 2 +- 4 files changed, 46 insertions(+), 49 deletions(-) diff --git a/xray/commands/audit/jas/applicability/applicabilitymanager.go b/xray/commands/audit/jas/applicability/applicabilitymanager.go index 90a318c36..1c52efadb 100644 --- a/xray/commands/audit/jas/applicability/applicabilitymanager.go +++ b/xray/commands/audit/jas/applicability/applicabilitymanager.go @@ -21,11 +21,11 @@ const ( ) type ApplicabilityScanManager struct { - applicabilityScanResults []*sarif.Run - directDependenciesCves []string - xrayResults []services.ScanResponse - scanner *jas.JasScanner - thirdPartyApplicabilityScan bool + applicabilityScanResults []*sarif.Run + directDependenciesCves []string + xrayResults []services.ScanResponse + scanner *jas.JasScanner + thirdPartyScan bool } // The getApplicabilityScanResults function runs the applicability scan flow, which includes the following steps: @@ -52,14 +52,14 @@ func RunApplicabilityScan(xrayResults []services.ScanResponse, directDependencie return } -func newApplicabilityScanManager(xrayScanResults []services.ScanResponse, directDependencies []string, scanner *jas.JasScanner, thirdPartyApplicabilityScan bool) (manager *ApplicabilityScanManager) { +func newApplicabilityScanManager(xrayScanResults []services.ScanResponse, directDependencies []string, scanner *jas.JasScanner, thirdPartyScan bool) (manager *ApplicabilityScanManager) { directDependenciesCves := extractDirectDependenciesCvesFromScan(xrayScanResults, directDependencies) return &ApplicabilityScanManager{ - applicabilityScanResults: []*sarif.Run{}, - directDependenciesCves: directDependenciesCves, - xrayResults: xrayScanResults, - scanner: scanner, - thirdPartyApplicabilityScan: thirdPartyApplicabilityScan, + applicabilityScanResults: []*sarif.Run{}, + directDependenciesCves: directDependenciesCves, + xrayResults: xrayScanResults, + scanner: scanner, + thirdPartyScan: thirdPartyScan, } } @@ -144,9 +144,9 @@ type scanConfiguration struct { func (asm *ApplicabilityScanManager) createConfigFile(workingDir string) error { skipDirs := jas.SkippedDirs // If set to true, remove third party folders from the scan skip list. - if asm.thirdPartyApplicabilityScan { - // Only npm supported - skipDirs = removeElementFromArray(skipDirs, jas.NpmSkipPattern) + if asm.thirdPartyScan { + log.Debug("Including node modules in applicability scan") + skipDirs = removeElementFromSlice(skipDirs, jas.NodeModulesPattern) } configFileContent := applicabilityScanConfig{ Scans: []scanConfiguration{ @@ -169,12 +169,7 @@ func (asm *ApplicabilityScanManager) runAnalyzerManager() error { return asm.scanner.AnalyzerManager.Exec(asm.scanner.ConfigFileName, applicabilityScanCommand, filepath.Dir(asm.scanner.AnalyzerManager.AnalyzerManagerFullPath), asm.scanner.ServerDetails) } -func removeElementFromArray(arr []string, elementToRemove string) []string { - var result []string - for _, element := range arr { - if element != elementToRemove { - result = append(result, element) - } - } - return result +func removeElementFromSlice(skipDirs []string, element string) []string { + deleteIndex := slices.Index(skipDirs, element) + return slices.Delete(skipDirs, deleteIndex, deleteIndex+1) } diff --git a/xray/commands/audit/jas/common.go b/xray/commands/audit/jas/common.go index 60362d80d..1f4082bfe 100644 --- a/xray/commands/audit/jas/common.go +++ b/xray/commands/audit/jas/common.go @@ -20,11 +20,11 @@ import ( ) const ( - NpmSkipPattern = "**/*node_modules*/**" + NodeModulesPattern = "**/*node_modules*/**" ) var ( - SkippedDirs = []string{"**/*test*/**", "**/*venv*/**", NpmSkipPattern, "**/*target*/**"} + SkippedDirs = []string{"**/*test*/**", "**/*venv*/**", NodeModulesPattern, "**/*target*/**"} mapSeverityToScore = map[string]string{ "": "0.0", diff --git a/xray/utils/resultstable.go b/xray/utils/resultstable.go index 99ce83120..59ffe7d1e 100644 --- a/xray/utils/resultstable.go +++ b/xray/utils/resultstable.go @@ -3,6 +3,7 @@ package utils import ( "fmt" "os" + "path/filepath" "sort" "strconv" "strings" @@ -93,8 +94,11 @@ func prepareViolations(violations []services.Violation, extendedResults *Extende case "security": cves := convertCves(violation.Cves) applicableValue := getApplicableCveValue(extendedResults, cves) - for i, cve := range cves { - cves[i].Applicability = getCveApplicability(cve, extendedResults.ApplicabilityScanResults, nil) + if extendedResults.EntitledForJas { + for i, cve := range cves { + cves[i].Applicability = getCveApplicability(cve, extendedResults.ApplicabilityScanResults, nil) + applicableValue = ApplicabilityStatus(cves[i].Applicability.Status) + } } currSeverity := GetSeverity(violation.Severity, applicableValue) jfrogResearchInfo := convertJfrogResearchInformation(violation.ExtendedInformation) @@ -213,8 +217,11 @@ func prepareVulnerabilities(vulnerabilities []services.Vulnerability, extendedRe } cves := convertCves(vulnerability.Cves) applicableValue := getApplicableCveValue(extendedResults, cves) - for i, cve := range cves { - cves[i].Applicability = getCveApplicability(cve, extendedResults.ApplicabilityScanResults, vulnerability.Components) + if extendedResults.EntitledForJas { + for i, cve := range cves { + cves[i].Applicability = getCveApplicability(cve, extendedResults.ApplicabilityScanResults, vulnerability.Components) + applicableValue = ApplicabilityStatus(cves[i].Applicability.Status) + } } currSeverity := GetSeverity(vulnerability.Severity, applicableValue) jfrogResearchInfo := convertJfrogResearchInformation(vulnerability.ExtendedInformation) @@ -954,20 +961,14 @@ func getApplicableCveValue(extendedResults *ExtendedScanResults, xrayCves []form return ApplicabilityUndetermined } -func getCveApplicability(cve formats.CveRow, applicabilityScanResults []*sarif.Run, components map[string]services.Component) (applicability *formats.Applicability) { - applicability = &formats.Applicability{Status: string(ApplicabilityUndetermined)} +func getCveApplicability(cve formats.CveRow, applicabilityScanResults []*sarif.Run, components map[string]services.Component) *formats.Applicability { + applicability := &formats.Applicability{Status: string(ApplicabilityUndetermined)} for _, applicabilityRun := range applicabilityScanResults { foundResult, _ := applicabilityRun.GetResultByRuleId(CveToApplicabilityRuleId(cve.Id)) if foundResult == nil { continue } 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) @@ -975,13 +976,13 @@ func getCveApplicability(cve formats.CveRow, applicabilityScanResults []*sarif.R // Add new evidences from locations for _, location := range foundResult.Locations { - fileName := GetLocationFileName(location) - if shouldDisqualifyNpmEvidence(components, fileName) { + fileName := GetRelativeLocationFileName(location, applicabilityRun.Invocations) + if shouldDisqualifyEvidence(components, fileName) { continue } applicability.Evidence = append(applicability.Evidence, formats.Evidence{ Location: formats.Location{ - File: GetRelativeLocationFileName(location, applicabilityRun.Invocations), + File: fileName, StartLine: GetLocationStartLine(location), StartColumn: GetLocationStartColumn(location), EndLine: GetLocationEndLine(location), @@ -991,14 +992,13 @@ func getCveApplicability(cve formats.CveRow, applicabilityScanResults []*sarif.R Reason: GetResultMsgText(foundResult), }) } - // When there are no evidences left, it means we disqualified some of the original evidences. - if len(applicability.Evidence) == 0 { - applicability.Status = string(NotApplicable) - return - } - break } - return + if len(applicability.Evidence) == 0 { + applicability.Status = string(NotApplicable) + } else { + applicability.Status = string(Applicable) + } + return applicability } func printApplicableCveValue(applicableValue ApplicabilityStatus, isTable bool) string { @@ -1024,13 +1024,15 @@ func printApplicableCveValue(applicableValue ApplicabilityStatus, isTable bool) // // filePath = myProject/node_modules/mpath/badCode.js , disqualify = False. // Found use of a badCode inside the node_modules from a different package, report applicable. -func shouldDisqualifyNpmEvidence(components map[string]services.Component, evidenceFilePath string) (disqualify bool) { +func shouldDisqualifyEvidence(components map[string]services.Component, evidenceFilePath string) (disqualify bool) { for key := range components { dependencyName := extractNpmDependencyNameFromComponent(key) if dependencyName == "" { return } - if strings.Contains(evidenceFilePath, nodeModules+"/"+dependencyName) { + // Check macOS and Linux path + linuxPath := nodeModules + "/" + dependencyName + if strings.Contains(evidenceFilePath, linuxPath) || strings.Contains(evidenceFilePath, filepath.Join(nodeModules, dependencyName)) { disqualify = true return } diff --git a/xray/utils/resultstable_test.go b/xray/utils/resultstable_test.go index fd47f4197..b400df255 100644 --- a/xray/utils/resultstable_test.go +++ b/xray/utils/resultstable_test.go @@ -669,7 +669,7 @@ func TestShouldDisqualifyEvidence(t *testing.T) { } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - assert.Equal(t, tc.disqualify, shouldDisqualifyNpmEvidence(tc.component, tc.filePath)) + assert.Equal(t, tc.disqualify, shouldDisqualifyEvidence(tc.component, tc.filePath)) }) } }