Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
1 change: 0 additions & 1 deletion audit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,6 @@ func testXrayAuditPip(t *testing.T, format, requirementsFile string) string {
args := []string{"audit", "--pip", "--licenses", "--format=" + format}
if requirementsFile != "" {
args = append(args, "--requirements-file="+requirementsFile)

}
return securityTests.PlatformCli.RunCliCmdWithOutput(t, args...)
}
Expand Down
2 changes: 1 addition & 1 deletion commands/audit/audit.go
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ func detectScanTargets(cmdResults *results.SecurityCommandResults, params *Audit
continue
}
if len(workingDirs) == 0 {
// Requested technology (from params) descriptors/indicators were not found, scan only requested directory for this technology.
// Requested technology (from params) descriptors/indicators were not found or recursive scan with NoTech value, add scan without descriptors.
cmdResults.NewScanResults(results.ScanTarget{Target: requestedDirectory, Technology: tech})
}
for workingDir, descriptors := range workingDirs {
Expand Down
2 changes: 1 addition & 1 deletion commands/audit/scarunner.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func hasAtLeastOneTech(cmdResults *results.SecurityCommandResults) bool {
return false
}
for _, scan := range cmdResults.Targets {
if scan.Technology != "" {
if scan.Technology != techutils.NoTech {
return true
}
}
Expand Down
58 changes: 58 additions & 0 deletions utils/techutils/techutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const (
Docker Technology = "docker"
Oci Technology = "oci"
Conan Technology = "conan"
NoTech Technology = ""
)
const Pypi = "pypi"

Expand Down Expand Up @@ -322,6 +323,7 @@ func detectedTechnologiesListInPath(path string, recursive bool) (technologies [
}

// If recursive is true, the search will not be limited to files in the root path.
// If recursive is true the search may return Technology.NoTech value
// If requestedTechs is empty, all technologies will be checked.
// If excludePathPattern is not empty, files/directories that match the wildcard pattern will be excluded from the search.
func DetectTechnologiesDescriptors(path string, recursive bool, requestedTechs []string, requestedDescriptors map[Technology][]string, excludePathPattern string) (technologiesDetected map[Technology]map[string][]string, err error) {
Expand All @@ -340,12 +342,68 @@ func DetectTechnologiesDescriptors(path string, recursive bool, requestedTechs [
log.Debug(fmt.Sprintf("mapped %d working directories with indicators/descriptors:\n%s", len(workingDirectoryToIndicators), strJson))
}
technologiesDetected, err = mapWorkingDirectoriesToTechnologies(workingDirectoryToIndicators, excludedTechAtWorkingDir, ToTechnologies(requestedTechs), requestedDescriptors)
if err != nil {
return
}
if recursive {
// If recursive search, we need to also make sure to include directories that do not have any technology indicators.
technologiesDetected, err = addNoTechIfNeeded(technologiesDetected, path, excludePathPattern)
}
// In case we have recursive search, and the
if len(technologiesDetected) > 0 {
log.Debug(fmt.Sprintf("Detected %d technologies at %s: %s.", len(technologiesDetected), path, maps.Keys(technologiesDetected)))
}
return
}

func addNoTechIfNeeded(technologiesDetected map[Technology]map[string][]string, path, excludePathPattern string) (finalMap map[Technology]map[string][]string, err error) {
finalMap = technologiesDetected
noTechMap := map[string][]string{}
directories, err := getDirectDirectories(path, excludePathPattern)
if err != nil {
return
}
for _, dir := range directories {
// Check if the directory is already mapped to a technology
isMapped := false
for _, techDirs := range finalMap {
if _, exist := techDirs[dir]; exist {
isMapped = true
break
}
}
if !isMapped {
// Add the directory to NoTech (no indicators/descriptors were found)
noTechMap[dir] = []string{}
}
}
if len(technologiesDetected) == 0 || len(noTechMap) > 0 {
// no technologies detected at all (add NoTech without any directories) or some directories were added to NoTech
finalMap[NoTech] = noTechMap
}
return
}

func getDirectDirectories(path, excludePathPattern string) (directories []string, err error) {
// Get all files and directories in the path, not recursive
filesOrDirsInPath, err := fspatterns.ListFiles(path, false, true, true, true, excludePathPattern)
if err != nil {
return
}
// Filter to directories only
for _, potentialDir := range filesOrDirsInPath {
isDir, e := fileutils.IsDirExists(potentialDir, true)
if e != nil {
err = errors.Join(err, fmt.Errorf("failed to check if %s is a directory: %w", potentialDir, e))
continue
}
if isDir {
directories = append(directories, potentialDir)
}
}
return
}

// Map files to relevant working directories according to the technologies' indicators/descriptors and requested descriptors.
// files: The file paths to map.
// requestedDescriptors: Special requested descriptors (for example in Pip requirement.txt can have different path) for each technology.
Expand Down