Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
17 changes: 17 additions & 0 deletions commands/audit/audit.go
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,13 @@ func isEntitledForSnippetDetection(isEntitledForJas bool, xrayManager *xray.Xray
func populateScanTargets(cmdResults *results.SecurityCommandResults, params *AuditParams) {
// Populate x scan targets based on the provided parameters.
detectScanTargets(cmdResults, params)
if detectedTechsGuardCallback := params.DetectedTechnologiesGuardCallback(); detectedTechsGuardCallback != nil {
if err := detectedTechsGuardCallback(collectDetectedTechnologies(cmdResults)); err != nil {
// allowSkippingError is hardcoded to false: this check must never be bypassable via AllowPartialResults.
cmdResults.AddGeneralError(err, false)
return
}
Comment thread
eranturgeman marked this conversation as resolved.
Outdated
}
// Populate target information for the scans
for _, targetResult := range cmdResults.Targets {
// Generate SBOM for the target if requested or for SCA scans.
Expand Down Expand Up @@ -663,6 +670,16 @@ func createScanTarget(root string, exclude []string, includes ...string) *result
return &results.ScanTarget{Target: root, Include: include, Exclude: exclude}
}

func collectDetectedTechnologies(cmdResults *results.SecurityCommandResults) []techutils.Technology {
detected := datastructures.MakeSet[techutils.Technology]()
for _, targetResult := range cmdResults.Targets {
for _, tech := range targetResult.Technologies {
detected.Add(tech)
}
}
return detected.ToSlice()
}
Comment thread
eranturgeman marked this conversation as resolved.
Outdated

func detectTechnologiesInTarget(target results.ScanTarget, otherParams *AuditParams) (technologies []techutils.Technology) {
detectedTechnologies := datastructures.MakeSet[techutils.Technology]()
for _, included := range jas.GetRootsFromTarget(target) {
Expand Down
44 changes: 44 additions & 0 deletions commands/audit/audit_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package audit

import (
"errors"
"fmt"
"net/http"
"os"
Expand Down Expand Up @@ -603,6 +604,49 @@ func TestDetectScanTargetsNewFlowCliExcludedCwdWithNonExcludedInclude(t *testing
assert.True(t, hasNpm, "expected Npm among detected technologies")
}

func TestPopulateScanTargetsDetectedTechnologiesGuardCallbackIsNotSkippable(t *testing.T) {
baseDir, cleanUp := createTestDir(t)
defer cleanUp()

mavenDir := filepath.Join(baseDir, "maven-wd")
assert.NoError(t, os.MkdirAll(mavenDir, 0o755))
createEmptyFile(t, filepath.Join(mavenDir, "pom.xml"))

callbackErr := errors.New("environment guard failed")

tests := []struct {
name string
allowPartialResults bool
}{
{
name: "Partial results disabled - fail upon every error",
allowPartialResults: false,
},
{
name: "allowPartialResults=true - callback error must still propagate",
allowPartialResults: true,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
cmdRes := results.NewCommandResults(utils.SourceCode).SetEntitledForJas(true).SetSecretValidation(true).SetAllowPartialResults(tt.allowPartialResults)
params := NewAuditParams()
params.SetWorkingDirs([]string{mavenDir})
params.SetIsRecursiveScan(false)
params.SetBomGenerator(xrayplugin.NewXrayLibBomGenerator())
params.SetDetectedTechnologiesGuardCallback(func(detected []techutils.Technology) error {
return callbackErr
})

populateScanTargets(cmdRes, params)

// The callback error must surface via GetErrors() regardless of AllowPartialResults
assert.ErrorContains(t, cmdRes.GetErrors(), callbackErr.Error())
})
}
}

func TestShouldGenerateSbom(t *testing.T) {
configProfileModulesWithSca := []services.Module{{
ScanConfig: services.ScanConfig{
Expand Down
23 changes: 17 additions & 6 deletions commands/audit/auditparams.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,14 @@ type AuditParams struct {
appsConfig *jfrogappsconfig.JFrogAppsConfig
workingDirs []string
// Common params to all scan routines
resultsContext results.ResultContext
gitContext *xscServices.XscGitInfoContext
rootDir string
installFunc func(tech string) error
fixableOnly bool
minSeverityFilter severityutils.Severity
resultsContext results.ResultContext
gitContext *xscServices.XscGitInfoContext
rootDir string
installFunc func(tech string) error
// Optional hook invoked once technologies are detected for all targets, before any SBOM/dependency-tree generation runs (i.e. before any build-tool plugin executes untrusted code). A non-nil error aborts the scan.
detectedTechnologiesGuardCallback func(detectedTechnologies []techutils.Technology) error
fixableOnly bool
minSeverityFilter severityutils.Severity
*AuditBasicParams
multiScanId string
// Include third party dependencies source code in the applicability scan.
Expand Down Expand Up @@ -163,6 +165,15 @@ func (params *AuditParams) SetInstallFunc(installFunc func(tech string) error) *
return params
}

func (params *AuditParams) SetDetectedTechnologiesGuardCallback(callback func(detectedTechnologies []techutils.Technology) error) *AuditParams {
params.detectedTechnologiesGuardCallback = callback
return params
}

func (params *AuditParams) DetectedTechnologiesGuardCallback() func(detectedTechnologies []techutils.Technology) error {
return params.detectedTechnologiesGuardCallback
}

func (params *AuditParams) FixableOnly() bool {
return params.fixableOnly
}
Expand Down
Loading