Skip to content

Commit

Permalink
continue
Browse files Browse the repository at this point in the history
  • Loading branch information
attiasas committed Oct 9, 2024
1 parent 1e80cf1 commit 85bcef8
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 16 deletions.
32 changes: 24 additions & 8 deletions commands/audit/scarunner.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,20 +140,22 @@ func getRequestedDescriptors(params *AuditParams) map[techutils.Technology][]str

// Preform the SCA scan for the given scan information.
func executeScaScanTask(auditParallelRunner *utils.SecurityParallelRunner, serverDetails *config.ServerDetails, auditParams *AuditParams,
scan *xrayutils.ScaScanResult, treeResult *technologies.DependencyTreeResult) parallel.TaskFunc {
scan *xrayutils.ScaScanResult, treeResult *techutils.TechnologyDependencyTrees) parallel.TaskFunc {
return func(threadId int) (err error) {
log.Info(clientutils.GetLogMsgPrefix(threadId, false)+"Running SCA scan for", scan.Target, "vulnerable dependencies in", scan.Target, "directory...")
defer func() {
auditParallelRunner.ScaScansWg.Done()
}()
// Scan the dependency tree.
scanResults, xrayErr := runScaWithTech(scan.Technology, auditParams, serverDetails, *treeResult.FlatTree, treeResult.FullDepTrees)
flatTree := treeResult.GetAsXrayScaScanParam()
fullDepTrees := treeResult.GetUnifiedTree()
scanResults, xrayErr := runScaWithTech(scan.Technology, auditParams, serverDetails, *flatTree, fullDepTrees)
if xrayErr != nil {
return fmt.Errorf("%s Xray dependency tree scan request on '%s' failed:\n%s", clientutils.GetLogMsgPrefix(threadId, false), scan.Technology, xrayErr.Error())
}
scan.IsMultipleRootProject = clientutils.Pointer(len(treeResult.FullDepTrees) > 1)
scan.IsMultipleRootProject = clientutils.Pointer(len(fullDepTrees) > 1)
auditParallelRunner.ResultsMu.Lock()
addThirdPartyDependenciesToParams(auditParams, scan.Technology, treeResult.FlatTree, treeResult.FullDepTrees)
addThirdPartyDependenciesToParams(auditParams, scan.Technology, flatTree, fullDepTrees)
scan.XrayResults = append(scan.XrayResults, scanResults...)
err = dumpScanResponseToFileIfNeeded(scanResults, auditParams.scanResultsOutputDir, utils.ScaScan)
auditParallelRunner.ResultsMu.Unlock()
Expand Down Expand Up @@ -365,21 +367,35 @@ func SetResolutionRepoIfExists(params utils.AuditParams, tech techutils.Technolo
// return
// }

func getDependencyTreeDetectionParams(scan *utils.ScaScanResult, params *AuditParams, serverDetails *config.ServerDetails, curationCacheDir string) techutils.DetectDependencyTreeParams {
detectionParams := techutils.DetectDependencyTreeParams{Technology: scan.Technology, Descriptors: scan.Descriptors}
// Artifactory params
detectionParams.DependenciesRepository = params.DepsRepo()
// Curation optional params
detectionParams.IncludeCuration = params.IsCurationCmd()
detectionParams.ServerDetails = serverDetails
detectionParams.CurationCacheFolder = curationCacheDir
// Common params
detectionParams.UseWrapper = params.UseWrapper()
// Maven params
detectionParams.IsMavenDepTreeInstalled = params.IsMavenDepTreeInstalled()
return detectionParams
}

// This method will change the working directory to the scan's working directory.
func buildDependencyTree(scan *utils.ScaScanResult, params *AuditParams) (*technologies.DependencyTreeResult, error) {
func buildDependencyTree(scan *utils.ScaScanResult, params *AuditParams) (*techutils.TechnologyDependencyTrees, error) {
if err := os.Chdir(scan.Target); err != nil {
return nil, errorutils.CheckError(err)
}
serverDetails, err := SetResolutionRepoIfExists(params.AuditBasicParams, scan.Technology)
if err != nil {
return nil, err
}
// technologies.GetDependencyTree(techutils.DetectDependencyTreeParams{Technology: scan.Technology, Descriptors: scan.Descriptors})
treeResult, techErr := technologies.GetTechDependencyTree(params.AuditBasicParams, serverDetails, scan.Technology)
treeResult, techErr := technologies.GetDependencyTree(getDependencyTreeDetectionParams(scan, params, serverDetails))// technologies.GetTechDependencyTree(params.AuditBasicParams, serverDetails, scan.Technology)

Check failure on line 394 in commands/audit/scarunner.go

View workflow job for this annotation

GitHub Actions / Static-Check

not enough arguments in call to getDependencyTreeDetectionParams

Check failure on line 394 in commands/audit/scarunner.go

View workflow job for this annotation

GitHub Actions / Static-Check

not enough arguments in call to getDependencyTreeDetectionParams

Check failure on line 394 in commands/audit/scarunner.go

View workflow job for this annotation

GitHub Actions / Static-Check

not enough arguments in call to getDependencyTreeDetectionParams
if techErr != nil {
return nil, fmt.Errorf("failed while building '%s' dependency tree:\n%s", scan.Technology, techErr.Error())
}
if treeResult.FlatTree == nil || len(treeResult.FlatTree.Nodes) == 0 {
if len(treeResult.UniqueDependencies) == 0 {
return nil, errorutils.CheckErrorf("no dependencies were found. Please try to build your project and re-run the audit command")
}
return &treeResult, nil
Expand Down
31 changes: 31 additions & 0 deletions technologies/java/mvn.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package java

import (
"fmt"

"github.com/owenrumney/go-sarif/v2/sarif"

"github.com/jfrog/jfrog-cli-security/utils/techutils"
)

const (
mavenDepTreeJarFile = "maven-dep-tree.jar"
mavenDepTreeOutputFile = "mavendeptree.out"
// Changing this version also requires a change in MAVEN_DEP_TREE_VERSION within buildscripts/download_jars.sh
mavenDepTreeVersion = "1.1.1"
settingsXmlFile = "settings.xml"
)

type MavenTechnologyHandler struct {}

func (handler *MavenTechnologyHandler) GetTechDependencyTree(params techutils.DetectDependencyTreeParams) (techutils.TechnologyDependencyTrees, error) {
return techutils.TechnologyDependencyTrees{}, fmt.Errorf("Not implemented")
}

func (handler *MavenTechnologyHandler) GetTechDependencyLocations(directDependencyName, directDependencyVersion string, descriptorPaths ...string) ([]*sarif.Location, error) {
return nil, fmt.Errorf("Not implemented")
}

func (handler *MavenTechnologyHandler) ChangeTechDependencyVersion(directDependencyName, directDependencyVersion, fixVersion string, descriptorPaths ...string) error {
return fmt.Errorf("Not implemented")
}
62 changes: 58 additions & 4 deletions technologies/technologies.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"time"

"github.com/jfrog/build-info-go/utils/pythonutils"
"github.com/owenrumney/go-sarif/v2/sarif"

clientUtils "github.com/jfrog/jfrog-client-go/utils"
"github.com/jfrog/jfrog-client-go/utils/errorutils"
Expand All @@ -24,25 +25,78 @@ import (
"github.com/jfrog/jfrog-cli-security/commands/audit/sca/python"
"github.com/jfrog/jfrog-cli-security/commands/audit/sca/yarn"

javaHandlers "github.com/jfrog/jfrog-cli-security/technologies/java"

"github.com/jfrog/jfrog-cli-security/utils"
"github.com/jfrog/jfrog-cli-security/utils/techutils"
"github.com/jfrog/jfrog-cli-security/utils/xray"
)

var TechnologyHandlers = map[techutils.Technology]techutils.TechnologyHandler{
// Java technologies
techutils.Maven: &javaHandlers.MavenTechnologyHandler{},
}

func GetTechHandler(tech techutils.Technology) (techutils.TechnologyHandler, error) {
if handler, ok := TechnologyHandlers[tech]; ok {
return handler, nil
}
return nil, fmt.Errorf("%s is currently not supported", tech.ToFormal())
}

func GetTechDependencyLocations(tech techutils.Technology, directDependencyName, directDependencyVersion string, descriptorPaths ...string) ([]*sarif.Location, error) {
handler, err := GetTechHandler(tech)
if err != nil {
return nil, err
}
return handler.GetTechDependencyLocations(directDependencyName, directDependencyVersion, descriptorPaths...)
}

func GetDependencyTree(params techutils.DetectDependencyTreeParams) (*techutils.TechnologyDependencyTrees, error) {
if handler, ok := TechnologyHandlers[params.Technology]; ok {
func ChangeTechDependencyVersion(tech techutils.Technology, directDependencyName, directDependencyVersion, fixVersion string, descriptorPaths ...string) error {
handler, err := GetTechHandler(tech)
if err != nil {
return err
}
return handler.ChangeTechDependencyVersion(directDependencyName, directDependencyVersion, fixVersion, descriptorPaths...)
}

func GetDependencyTree(params techutils.DetectDependencyTreeParams) (techutils.TechnologyDependencyTrees, error) {
if handler, err := GetTechHandler(params.Technology); err == nil {
log.Info(fmt.Sprintf("Handler Calculating %s dependencies...", params.Technology.ToFormal()))
if tree, err := handler.GetTechDependencyTree(params); err == nil {
return tree, nil
}
log.Warn(fmt.Sprintf("Handler failed to calculate %s dependencies, falling back to default handler", params.Technology.ToFormal()))
return techutils.TechnologyDependencyTrees{}, fmt.Errorf("Handler failed to calculate %s dependencies", params.Technology.ToFormal())
}
return runFallback(params)
}

func runFallback(params techutils.DetectDependencyTreeParams) (techutils.TechnologyDependencyTrees, error) {
log.Info(fmt.Sprintf("Calculating %s dependencies...", params.Technology.ToFormal()))
return nil, fmt.Errorf("%s is currently not supported", string(params.Technology))
auditParams := toAuditParams(params)
oldTreeStruct, err := GetTechDependencyTree(auditParams, params.ServerDetails, params.Technology)
if err != nil {
return techutils.TechnologyDependencyTrees{}, err
}
return toResultNewStruct(oldTreeStruct), nil
}

func toAuditParams(params techutils.DetectDependencyTreeParams) utils.AuditParams {
auditParams := &utils.AuditBasicParams{}
auditParams.SetServerDetails(params.ServerDetails)
return auditParams
}

func toResultNewStruct(oldTreeStruct DependencyTreeResult) techutils.TechnologyDependencyTrees {
uniqueDeps := make([]string, 0, len(oldTreeStruct.FlatTree.Nodes))
for _, node := range oldTreeStruct.FlatTree.Nodes {
uniqueDeps = append(uniqueDeps, node.Id)
}
tree := map[string]*xrayUtils.GraphNode{}
for _, node := range oldTreeStruct.FullDepTrees {
tree["root"] = node
}
return techutils.TechnologyDependencyTrees{DownloadUrls: oldTreeStruct.DownloadUrls, UniqueDependencies: uniqueDeps, DependencyTrees: tree}
}

type DependencyTreeResult struct {
Expand Down
32 changes: 28 additions & 4 deletions utils/techutils/techutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ import (
"regexp"
"strings"

"github.com/owenrumney/go-sarif/v2/sarif"
"golang.org/x/exp/maps"
"golang.org/x/text/cases"
"golang.org/x/text/language"
"github.com/owenrumney/go-sarif/v2/sarif"

"github.com/jfrog/gofrog/datastructures"
"github.com/jfrog/jfrog-cli-core/v2/common/project"
"github.com/jfrog/jfrog-cli-core/v2/utils/config"
"github.com/jfrog/jfrog-cli-core/v2/utils/coreutils"
"github.com/jfrog/jfrog-client-go/artifactory/services/fspatterns"
"github.com/jfrog/jfrog-client-go/utils/errorutils"
Expand Down Expand Up @@ -73,8 +74,22 @@ var TechToProjectType = map[Technology]project.ProjectType{

type DetectDependencyTreeParams struct {
Technology Technology `json:"technology"`
// If the tech need to create temp file for the output of the command it should output it to this path.
OutputDirPath string `json:"outputDirPath,omitempty"`
// Files that the technology handlers use to detect the project's dependencies.
Descriptors []string `json:"descriptors"`
// Artifactory related options
DependenciesRepository string `json:"dependenciesRepository,omitempty"`
// Curation related options
IncludeCuration bool `json:"includeCuration,omitempty"`
ServerDetails *config.ServerDetails `json:"artifactoryServerDetails,omitempty"`
CurationCacheFolder string `json:"curationCacheFolder,omitempty"`

// Common Tech options
UseWrapper bool `json:"useWrapper,omitempty"`

// Specific Maven options
IsMavenDepTreeInstalled bool `json:"isMavenDepTreeInstalled,omitempty"`
}

type TechnologyDependencyTrees struct {
Expand All @@ -90,17 +105,24 @@ func (tdr TechnologyDependencyTrees) GetAsXrayScaScanParam() *xrayUtils.GraphNod
}
}

func (tdr TechnologyDependencyTrees) GetUnifiedTree() []*xrayUtils.GraphNode {
return []*xrayUtils.GraphNode{}
}

type TechnologyHandler interface {
// Get a dependency tree for each descriptor file, the tree will have a root node id with the descriptor/project id, second level nodes are the direct dependencies...
// If no descriptor files are provided, the handler will try to use cwd as the context to find the dependencies.
GetTechDependencyTree(params DetectDependencyTreeParams) (*TechnologyDependencyTrees, error)
GetTechDependencyTree(params DetectDependencyTreeParams) (TechnologyDependencyTrees, error)
// Get the locations of the direct dependency in the given descriptor files. if no descriptor files are provided, the handler will try to find at cwd.
GetTechDependencyLocations(directDependencyName, directDependencyVersion string, descriptorPaths ...string) ([]*sarif.Location, error)
GetTechDependencyLocations(directDependencyName, directDependencyVersion string, descriptorPaths ...string) ([]*sarif.Location, error) // maybe ([]formats.ComponentRow, error)
// Change a direct dependency version in the given descriptor files. if no descriptor files are provided, the handler will try to find at cwd.
FixTechDependencyVersion(directDependencyName, directDependencyVersion, fixVersion string, descriptorPaths ...string) error
ChangeTechDependencyVersion(directDependencyName, directDependencyVersion, fixVersion string, descriptorPaths ...string) error
}

type TechData struct {
techIdentifier string


// The name of the package type used in this technology.
packageType string
// Suffixes of file/directory names that indicate if a project uses this technology.
Expand Down Expand Up @@ -130,11 +152,13 @@ var technologiesData = map[Technology]TechData{
Maven: {
indicators: []string{"pom.xml"},
packageDescriptors: []string{"pom.xml"},
techIdentifier: "gav",
execCommand: "mvn",
},
Gradle: {
indicators: []string{"build.gradle", "build.gradle.kts"},
packageDescriptors: []string{"build.gradle", "build.gradle.kts"},
techIdentifier: "gav",
},
Npm: {
indicators: []string{"package.json", "package-lock.json", "npm-shrinkwrap.json"},
Expand Down

0 comments on commit 85bcef8

Please sign in to comment.