diff --git a/xray/audit/jas/applicabilitymanager.go b/xray/audit/jas/applicabilitymanager.go index 818a66481..f42a3cb75 100644 --- a/xray/audit/jas/applicabilitymanager.go +++ b/xray/audit/jas/applicabilitymanager.go @@ -120,7 +120,8 @@ func newApplicabilityScanManager(xrayScanResults []services.ScanResponse, depend } func (a *ApplicabilityScanManager) eligibleForApplicabilityScan() bool { - return resultsIncludeEligibleTechnologies(getXrayVulnerabilities(a.xrayResults), getXrayViolations(a.xrayResults)) + return resultsIncludeEligibleTechnologies(getXrayVulnerabilities(a.xrayResults), getXrayViolations(a.xrayResults)) && + !utils.ExcludeScan(scannersToExclude, ApplicabilityFeatureId) } // This function gets a liat of xray scan responses that contains direct and indirect violations, and returns only direct diff --git a/xray/audit/jas/applicabilitymanager_test.go b/xray/audit/jas/applicabilitymanager_test.go index d7c06cbd6..04cc9063f 100644 --- a/xray/audit/jas/applicabilitymanager_test.go +++ b/xray/audit/jas/applicabilitymanager_test.go @@ -411,7 +411,7 @@ func TestGetExtendedScanResults_AnalyzerManagerReturnsError(t *testing.T) { analyzerManagerExecuter = &analyzerManagerMock{} // Act - extendedResults, err := GetExtendedScanResults(fakeBasicXrayResults, fakeBasicDependencyGraph, &fakeServerDetails) + extendedResults, err := GetExtendedScanResults(fakeBasicXrayResults, fakeBasicDependencyGraph, &fakeServerDetails, "") // Assert assert.Error(t, err) diff --git a/xray/audit/jas/iacscanner.go b/xray/audit/jas/iacscanner.go index 291fa1452..ee3971b9b 100644 --- a/xray/audit/jas/iacscanner.go +++ b/xray/audit/jas/iacscanner.go @@ -48,6 +48,9 @@ func getIacScanResults(serverDetails *config.ServerDetails, analyzerManager util err = errors.Join(err, cleanupFunc()) } }() + if utils.ExcludeScan(scannersToExclude, iacScanCommand) { + return nil, false, nil + } if err = iacScanManager.run(); err != nil { if utils.IsNotEntitledError(err) || utils.IsUnsupportedCommandError(err) { return nil, false, nil diff --git a/xray/audit/jas/jasmanager.go b/xray/audit/jas/jasmanager.go index d24ca8beb..2ef659ec9 100644 --- a/xray/audit/jas/jasmanager.go +++ b/xray/audit/jas/jasmanager.go @@ -10,6 +10,7 @@ import ( "github.com/jfrog/jfrog-client-go/xray/services" xrayUtils "github.com/jfrog/jfrog-client-go/xray/services/utils" "os" + "strings" ) const serverDetailsErrorMessage = "cant get xray server details" @@ -17,10 +18,11 @@ const serverDetailsErrorMessage = "cant get xray server details" var ( analyzerManagerExecuter utils.AnalyzerManagerInterface = &utils.AnalyzerManager{} skippedDirs = []string{"**/*test*/**", "**/*venv*/**", "**/*node_modules*/**", "**/*target*/**"} + scannersToExclude = []string{} ) func GetExtendedScanResults(xrayResults []services.ScanResponse, dependencyTrees []*xrayUtils.GraphNode, - serverDetails *config.ServerDetails) (*utils.ExtendedScanResults, error) { + serverDetails *config.ServerDetails, excludeScan string) (*utils.ExtendedScanResults, error) { if serverDetails == nil { return nil, errors.New(serverDetailsErrorMessage) } @@ -39,6 +41,7 @@ func GetExtendedScanResults(xrayResults []services.ScanResponse, dependencyTrees if err = utils.CreateAnalyzerManagerLogDir(); err != nil { return nil, err } + scannersToExclude = strings.Split(excludeScan, ";") applicabilityScanResults, eligibleForApplicabilityScan, err := getApplicabilityScanResults(xrayResults, dependencyTrees, serverDetails, analyzerManagerExecuter) if err != nil { diff --git a/xray/audit/jas/jasmanager_test.go b/xray/audit/jas/jasmanager_test.go index 9fd56367b..2eae0823d 100644 --- a/xray/audit/jas/jasmanager_test.go +++ b/xray/audit/jas/jasmanager_test.go @@ -63,7 +63,7 @@ func TestGetExtendedScanResults_AnalyzerManagerDoesntExist(t *testing.T) { analyzerManagerExecuter = &analyzerManagerMock{} // Act - extendedResults, err := GetExtendedScanResults(fakeBasicXrayResults, fakeBasicDependencyGraph, &fakeServerDetails) + extendedResults, err := GetExtendedScanResults(fakeBasicXrayResults, fakeBasicDependencyGraph, &fakeServerDetails, "") // Assert assert.NoError(t, err) @@ -74,10 +74,24 @@ func TestGetExtendedScanResults_AnalyzerManagerDoesntExist(t *testing.T) { func TestGetExtendedScanResults_ServerNotValid(t *testing.T) { // Act - extendedResults, err := GetExtendedScanResults(fakeBasicXrayResults, fakeBasicDependencyGraph, nil) + extendedResults, err := GetExtendedScanResults(fakeBasicXrayResults, fakeBasicDependencyGraph, nil, "") // Assert assert.Nil(t, extendedResults) assert.Error(t, err) assert.Equal(t, "cant get xray server details", err.Error()) } + +func TestGetExtendedScanResults_ExcludeScanners(t *testing.T) { + // Arrange + excludeScansInput := "contextual_analysis;secrets;iac" + + // Act + extendedResults, err := GetExtendedScanResults(fakeBasicXrayResults, fakeBasicDependencyGraph, &fakeServerDetails, excludeScansInput) + + // Assert + assert.NoError(t, err) + assert.False(t, extendedResults.EligibleForSecretScan) + assert.False(t, extendedResults.EligibleForApplicabilityScan) + assert.False(t, extendedResults.EligibleForIacScan) +} diff --git a/xray/audit/jas/secretsscanner.go b/xray/audit/jas/secretsscanner.go index c249afff6..0677d9f04 100644 --- a/xray/audit/jas/secretsscanner.go +++ b/xray/audit/jas/secretsscanner.go @@ -19,6 +19,7 @@ const ( secretsScannersNames = "tokens, entropy" secretsScannerType = "secrets-scan" secScanFailureMessage = "failed to run secrets scan. Cause: %s" + secretsFeatureName = "secrets" ) type SecretScanManager struct { @@ -49,6 +50,9 @@ func getSecretsScanResults(serverDetails *config.ServerDetails, analyzerManager err = errors.Join(err, cleanupFunc()) } }() + if utils.ExcludeScan(scannersToExclude, secretsFeatureName) { + return nil, false, nil + } if err = secretScanManager.run(); err != nil { if utils.IsNotEntitledError(err) || utils.IsUnsupportedCommandError(err) { return nil, false, nil diff --git a/xray/commands/audit/generic/auditmanager.go b/xray/commands/audit/generic/auditmanager.go index 6534532fb..2ae9b077c 100644 --- a/xray/commands/audit/generic/auditmanager.go +++ b/xray/commands/audit/generic/auditmanager.go @@ -36,6 +36,7 @@ type Params struct { installFunc func(tech string) error fixableOnly bool minSeverityFilter string + excludeJasScan string *clientUtils.GraphBasicParams xrayVersion string } @@ -106,6 +107,11 @@ func (params *Params) SetXrayVersion(version string) *Params { return params } +func (params *Params) SetExcludeJasScan(excludeScan string) *Params { + params.excludeJasScan = excludeScan + return params +} + // Runs an audit scan based on the provided auditParams. // Returns an audit Results object containing all the scan results. // If the current server is entitled for JAS, the advanced security results will be included in the scan results. @@ -137,7 +143,7 @@ func RunAudit(auditParams *Params) (results *Results, err error) { extendedScanResults := &clientUtils.ExtendedScanResults{XrayResults: scanResults} // Try to run contextual analysis only if the user is entitled for advance security if isEntitled { - extendedScanResults, err = jas.GetExtendedScanResults(scanResults, auditParams.FullDependenciesTree(), serverDetails) + extendedScanResults, err = jas.GetExtendedScanResults(scanResults, auditParams.FullDependenciesTree(), serverDetails, auditParams.excludeJasScan) if err != nil { return } diff --git a/xray/commands/audit/generic/generic.go b/xray/commands/audit/generic/generic.go index 16b7e4fa4..bfad9d222 100644 --- a/xray/commands/audit/generic/generic.go +++ b/xray/commands/audit/generic/generic.go @@ -12,6 +12,7 @@ type GenericAuditCommand struct { watches []string projectKey string targetRepoPath string + excludeJasScan string IncludeVulnerabilities bool IncludeLicenses bool Fail bool @@ -64,6 +65,11 @@ func (auditCmd *GenericAuditCommand) SetPrintExtendedTable(printExtendedTable bo return auditCmd } +func (auditCmd *GenericAuditCommand) SetExcludeJasScan(excludeScan string) *GenericAuditCommand { + auditCmd.excludeJasScan = excludeScan + return auditCmd +} + func (auditCmd *GenericAuditCommand) CreateXrayGraphScanParams() *services.XrayGraphScanParams { params := &services.XrayGraphScanParams{ RepoPath: auditCmd.targetRepoPath, @@ -86,7 +92,8 @@ func (auditCmd *GenericAuditCommand) Run() (err error) { SetWorkingDirs(auditCmd.workingDirs). SetMinSeverityFilter(auditCmd.minSeverityFilter). SetFixableOnly(auditCmd.fixableOnly). - SetGraphBasicParams(auditCmd.GraphBasicParams) + SetGraphBasicParams(auditCmd.GraphBasicParams). + SetExcludeJasScan(auditCmd.excludeJasScan) auditResults, err := RunAudit(auditParams) if err != nil { return err diff --git a/xray/utils/analyzermanager.go b/xray/utils/analyzermanager.go index e9181084e..6436cfcd9 100644 --- a/xray/utils/analyzermanager.go +++ b/xray/utils/analyzermanager.go @@ -243,3 +243,12 @@ func GetResultSeverity(result *sarif.Result) string { } return SeverityDefaultValue } + +func ExcludeScan(scansToBeExcluded []string, scan string) bool { + for _, s := range scansToBeExcluded { + if s == scan { + return true + } + } + return false +} diff --git a/xray/utils/analyzermanager_test.go b/xray/utils/analyzermanager_test.go index ce90b5210..be6e90e4c 100644 --- a/xray/utils/analyzermanager_test.go +++ b/xray/utils/analyzermanager_test.go @@ -133,3 +133,20 @@ func TestGetResultSeverity(t *testing.T) { assert.Equal(t, test.expectedSeverity, GetResultSeverity(test.result)) } } + +func TestExcludeScan(t *testing.T) { + tests := []struct { + excludedScanList []string + scanToCheck string + expectedResult bool + }{ + {excludedScanList: []string{"secrets", "iac", "contextual_analysis"}, scanToCheck: "contextual_analysis", expectedResult: true}, + {excludedScanList: []string{"secrets", "iac"}, scanToCheck: "contextual_analysis", expectedResult: false}, + {excludedScanList: []string{}, scanToCheck: "contextual_analysis", expectedResult: false}, + {excludedScanList: []string{"", "unsupported_Scan_type", "contextual_analysis"}, scanToCheck: "contextual_analysis", expectedResult: true}, + } + + for _, test := range tests { + assert.Equal(t, test.expectedResult, ExcludeScan(test.excludedScanList, test.scanToCheck)) + } +}