Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SAST advance scan #919

Merged
merged 35 commits into from
Sep 3, 2023
Merged
Show file tree
Hide file tree
Changes from 32 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
bee1ad6
Refactor advanced security scanners
omerzi Aug 10, 2023
f437253
Merge branch 'dev' into refactor-scanners
omerzi Aug 10, 2023
99dd032
Refactor advanced security scanners
omerzi Aug 10, 2023
ca7dc50
Merge remote-tracking branch 'origin/refactor-scanners' into refactor…
omerzi Aug 10, 2023
b60e877
Merge remote-tracking branch 'upstream/dev' into refactor-scanners
omerzi Aug 15, 2023
97adf0b
Fix tests
omerzi Aug 15, 2023
f477ff5
Merge remote-tracking branch 'upstream/dev' into refactor-scanners
omerzi Aug 16, 2023
1e9e5fd
update core
omerzi Aug 16, 2023
b666f49
update core
omerzi Aug 16, 2023
4042ff0
add init func to download analyzer manager
omerzi Aug 16, 2023
b44f607
add init func to download analyzer manager
omerzi Aug 16, 2023
92c0de4
add init func to download analyzer manager
omerzi Aug 16, 2023
710580a
initialize implementation of zeroday
attiasas Aug 21, 2023
67cd592
Merge remote-tracking branch 'upstream/dev' into add_zeroday_scan
attiasas Aug 27, 2023
854f55a
fix merge
attiasas Aug 27, 2023
8f6bd75
fix merge
attiasas Aug 27, 2023
3719410
Add SAST scan
attiasas Aug 28, 2023
4285873
fix static analysis
attiasas Aug 28, 2023
2efc239
fix tests
attiasas Aug 28, 2023
498f9c5
fix tests
attiasas Aug 28, 2023
418f783
Merge remote-tracking branch 'upstream/dev' into add_zeroday_scan
attiasas Aug 29, 2023
1f9bfca
change zeroday to sast
attiasas Aug 29, 2023
53e5287
start refactor and adding tests
attiasas Aug 29, 2023
2fb0ff4
cleanup tests
attiasas Aug 30, 2023
5dba16d
code review changes
attiasas Aug 30, 2023
1568e84
remove changes for severity - extract to other PR
attiasas Aug 30, 2023
b1383d2
review changes
attiasas Aug 30, 2023
fe4d4c4
refactor handling sarif, describe better
attiasas Aug 30, 2023
477f1ce
fix tests
attiasas Aug 30, 2023
34928b2
Merge remote-tracking branch 'upstream/dev' into add_zeroday_scan
attiasas Aug 31, 2023
05e9a08
add tests
attiasas Aug 31, 2023
177d8d5
limit sast to AM min ver 1.3
attiasas Aug 31, 2023
84332c3
Merge remote-tracking branch 'upstream/dev' into add_zeroday_scan
attiasas Sep 3, 2023
7b14d96
filter sast table if not in valid version
attiasas Sep 3, 2023
618743e
final review changes
attiasas Sep 3, 2023
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
10 changes: 7 additions & 3 deletions xray/audit/jas/applicabilitymanager.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package jas

import (
"path/filepath"
"strings"

"github.com/jfrog/gofrog/datastructures"
"github.com/jfrog/jfrog-cli-core/v2/utils/coreutils"
"github.com/jfrog/jfrog-cli-core/v2/xray/utils"
Expand All @@ -10,7 +13,6 @@ import (
"github.com/owenrumney/go-sarif/v2/sarif"
"golang.org/x/exp/maps"
"golang.org/x/exp/slices"
"strings"
)

const (
Expand Down Expand Up @@ -109,7 +111,9 @@ func (a *ApplicabilityScanManager) Run(wd string) (err error) {
return
}
var workingDirResults map[string]string
workingDirResults, err = a.getScanResults()
if workingDirResults, err = a.getScanResults(); err != nil {
return
}
for cve, result := range workingDirResults {
a.applicabilityScanResults[cve] = result
}
Expand Down Expand Up @@ -156,7 +160,7 @@ func (a *ApplicabilityScanManager) createConfigFile(workingDir string) error {
// Runs the analyzerManager app and returns a boolean to indicate whether the user is entitled for
// advance security feature
func (a *ApplicabilityScanManager) runAnalyzerManager() error {
return a.scanner.analyzerManager.Exec(a.scanner.configFileName, applicabilityScanCommand, a.scanner.serverDetails)
return a.scanner.analyzerManager.Exec(a.scanner.configFileName, applicabilityScanCommand, filepath.Dir(a.scanner.analyzerManager.AnalyzerManagerFullPath), a.scanner.serverDetails)
}

func (a *ApplicabilityScanManager) getScanResults() (map[string]string, error) {
Expand Down
188 changes: 62 additions & 126 deletions xray/audit/jas/applicabilitymanager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,48 +12,37 @@ import (
)

func TestNewApplicabilityScanManager_InputIsValid(t *testing.T) {
scanner, cleanUp := initJasTest(t)
defer cleanUp()
// Act
assert.NoError(t, rtutils.DownloadAnalyzerManagerIfNeeded())
scanner, err := NewAdvancedSecurityScanner(nil, &fakeServerDetails)
assert.NoError(t, err)
defer func() {
if scanner.scannerDirCleanupFunc != nil {
assert.NoError(t, scanner.scannerDirCleanupFunc())
}
}()
applicabilityManager := newApplicabilityScanManager(fakeBasicXrayResults, mockDirectDependencies, scanner)

// Assert
assert.NotEmpty(t, applicabilityManager)
assert.NotEmpty(t, applicabilityManager.scanner.configFileName)
assert.NotEmpty(t, applicabilityManager.scanner.resultsFileName)
assert.Equal(t, applicabilityManager.directDependenciesCves.Size(), 5)
if assert.NotNil(t, applicabilityManager) {
assert.NotEmpty(t, applicabilityManager.scanner.configFileName)
assert.NotEmpty(t, applicabilityManager.scanner.resultsFileName)
assert.Equal(t, applicabilityManager.directDependenciesCves.Size(), 5)
attiasas marked this conversation as resolved.
Show resolved Hide resolved
}
}

func TestNewApplicabilityScanManager_DependencyTreeDoesntExist(t *testing.T) {
scanner, cleanUp := initJasTest(t)
defer cleanUp()
// Act
assert.NoError(t, rtutils.DownloadAnalyzerManagerIfNeeded())
scanner, err := NewAdvancedSecurityScanner(nil, &fakeServerDetails)
assert.NoError(t, err)
defer func() {
if scanner.scannerDirCleanupFunc != nil {
assert.NoError(t, scanner.scannerDirCleanupFunc())
}
}()
applicabilityManager := newApplicabilityScanManager(fakeBasicXrayResults, nil, scanner)

// Assert
assert.NotEmpty(t, applicabilityManager)
assert.NotNil(t, applicabilityManager.scanner.scannerDirCleanupFunc)
assert.Len(t, applicabilityManager.scanner.workingDirs, 1)
assert.NotEmpty(t, applicabilityManager.scanner.configFileName)
assert.NotEmpty(t, applicabilityManager.scanner.resultsFileName)
assert.Equal(t, applicabilityManager.directDependenciesCves.Size(), 0)
if assert.NotNil(t, applicabilityManager) {
assert.NotNil(t, applicabilityManager.scanner.scannerDirCleanupFunc)
assert.Len(t, applicabilityManager.scanner.workingDirs, 1)
assert.NotEmpty(t, applicabilityManager.scanner.configFileName)
assert.NotEmpty(t, applicabilityManager.scanner.resultsFileName)
assert.Equal(t, applicabilityManager.directDependenciesCves.Size(), 0)
}
}

func TestNewApplicabilityScanManager_NoDirectDependenciesInScan(t *testing.T) {
// Arrange
assert.NoError(t, rtutils.DownloadAnalyzerManagerIfNeeded())
var noDirectDependenciesResults = []services.ScanResponse{
{
ScanId: "scanId_1",
Expand All @@ -75,47 +64,36 @@ func TestNewApplicabilityScanManager_NoDirectDependenciesInScan(t *testing.T) {
fakeBasicXrayResults[0].Violations[0].Components["issueId_2_non_direct_dependency"] = services.Component{}

// Act
scanner, err := NewAdvancedSecurityScanner(nil, &fakeServerDetails)
assert.NoError(t, err)
defer func() {
if scanner.scannerDirCleanupFunc != nil {
assert.NoError(t, scanner.scannerDirCleanupFunc())
}
}()
scanner, cleanUp := initJasTest(t)
defer cleanUp()
applicabilityManager := newApplicabilityScanManager(noDirectDependenciesResults, mockDirectDependencies, scanner)

// Assert
assert.NotEmpty(t, applicabilityManager)
assert.NotEmpty(t, applicabilityManager.scanner.configFileName)
assert.NotEmpty(t, applicabilityManager.scanner.resultsFileName)
// Non-direct dependencies should not be added
assert.Equal(t, 0, applicabilityManager.directDependenciesCves.Size())
if assert.NotNil(t, applicabilityManager) {
assert.NotEmpty(t, applicabilityManager.scanner.configFileName)
assert.NotEmpty(t, applicabilityManager.scanner.resultsFileName)
// Non-direct dependencies should not be added
assert.Equal(t, 0, applicabilityManager.directDependenciesCves.Size())
}
}

func TestNewApplicabilityScanManager_MultipleDependencyTrees(t *testing.T) {
// Arrange
assert.NoError(t, rtutils.DownloadAnalyzerManagerIfNeeded())

scanner, cleanUp := initJasTest(t)
defer cleanUp()
// Act
scanner, err := NewAdvancedSecurityScanner(nil, &fakeServerDetails)
assert.NoError(t, err)
defer func() {
if scanner.scannerDirCleanupFunc != nil {
assert.NoError(t, scanner.scannerDirCleanupFunc())
}
}()
applicabilityManager := newApplicabilityScanManager(fakeBasicXrayResults, mockMultiRootDirectDependencies, scanner)

// Assert
assert.NotEmpty(t, applicabilityManager)
assert.NotEmpty(t, applicabilityManager.scanner.configFileName)
assert.NotEmpty(t, applicabilityManager.scanner.resultsFileName)
assert.Equal(t, 5, applicabilityManager.directDependenciesCves.Size())
if assert.NotNil(t, applicabilityManager) {
assert.NotEmpty(t, applicabilityManager.scanner.configFileName)
assert.NotEmpty(t, applicabilityManager.scanner.resultsFileName)
assert.Equal(t, 5, applicabilityManager.directDependenciesCves.Size())
}
}

func TestNewApplicabilityScanManager_ViolationsDontExistInResults(t *testing.T) {
// Arrange
assert.NoError(t, rtutils.DownloadAnalyzerManagerIfNeeded())
noViolationScanResponse := []services.ScanResponse{
{
ScanId: "scanId_1",
Expand All @@ -126,28 +104,22 @@ func TestNewApplicabilityScanManager_ViolationsDontExistInResults(t *testing.T)
},
},
}
scanner, cleanUp := initJasTest(t)
defer cleanUp()

// Act
scanner, err := NewAdvancedSecurityScanner(nil, &fakeServerDetails)
assert.NoError(t, err)
defer func() {
if scanner.scannerDirCleanupFunc != nil {
assert.NoError(t, scanner.scannerDirCleanupFunc())
}
}()
applicabilityManager := newApplicabilityScanManager(noViolationScanResponse, mockDirectDependencies, scanner)

// Assert
assert.NoError(t, err)
assert.NotEmpty(t, applicabilityManager)
assert.NotEmpty(t, applicabilityManager.scanner.configFileName)
assert.NotEmpty(t, applicabilityManager.scanner.resultsFileName)
assert.Equal(t, 3, applicabilityManager.directDependenciesCves.Size())
if assert.NotNil(t, applicabilityManager) {
assert.NotEmpty(t, applicabilityManager.scanner.configFileName)
assert.NotEmpty(t, applicabilityManager.scanner.resultsFileName)
assert.Equal(t, 3, applicabilityManager.directDependenciesCves.Size())
}
}

func TestNewApplicabilityScanManager_VulnerabilitiesDontExist(t *testing.T) {
// Arrange
assert.NoError(t, rtutils.DownloadAnalyzerManagerIfNeeded())
noVulnerabilitiesScanResponse := []services.ScanResponse{
{
ScanId: "scanId_1",
Expand All @@ -158,33 +130,24 @@ func TestNewApplicabilityScanManager_VulnerabilitiesDontExist(t *testing.T) {
},
},
}
scanner, cleanUp := initJasTest(t)
defer cleanUp()

// Act
scanner, err := NewAdvancedSecurityScanner(nil, &fakeServerDetails)
assert.NoError(t, err)
defer func() {
if scanner.scannerDirCleanupFunc != nil {
assert.NoError(t, scanner.scannerDirCleanupFunc())
}
}()
applicabilityManager := newApplicabilityScanManager(noVulnerabilitiesScanResponse, mockDirectDependencies, scanner)

// Assert
assert.NotEmpty(t, applicabilityManager)
assert.NotEmpty(t, applicabilityManager.scanner.configFileName)
assert.NotEmpty(t, applicabilityManager.scanner.resultsFileName)
assert.Equal(t, 2, applicabilityManager.directDependenciesCves.Size())
if assert.NotNil(t, applicabilityManager) {
assert.NotEmpty(t, applicabilityManager.scanner.configFileName)
assert.NotEmpty(t, applicabilityManager.scanner.resultsFileName)
assert.Equal(t, 2, applicabilityManager.directDependenciesCves.Size())
}
}

func TestApplicabilityScanManager_ShouldRun_TechnologiesNotEligibleForScan(t *testing.T) {
assert.NoError(t, rtutils.DownloadAnalyzerManagerIfNeeded())
scanner, err := NewAdvancedSecurityScanner(nil, &fakeServerDetails)
assert.NoError(t, err)
defer func() {
if scanner.scannerDirCleanupFunc != nil {
assert.NoError(t, scanner.scannerDirCleanupFunc())
}
}()
scanner, cleanUp := initJasTest(t)
defer cleanUp()

results, err := getApplicabilityScanResults(fakeBasicXrayResults, mockDirectDependencies,
[]coreutils.Technology{coreutils.Nuget, coreutils.Go}, scanner)

Expand All @@ -195,16 +158,11 @@ func TestApplicabilityScanManager_ShouldRun_TechnologiesNotEligibleForScan(t *te

func TestApplicabilityScanManager_ShouldRun_ScanResultsAreEmpty(t *testing.T) {
// Arrange
assert.NoError(t, rtutils.DownloadAnalyzerManagerIfNeeded())
scanner, err := NewAdvancedSecurityScanner(nil, &fakeServerDetails)
assert.NoError(t, err)
defer func() {
if scanner.scannerDirCleanupFunc != nil {
assert.NoError(t, scanner.scannerDirCleanupFunc())
}
}()
scanner, cleanUp := initJasTest(t)
defer cleanUp()

applicabilityManager := newApplicabilityScanManager(nil, mockDirectDependencies, scanner)
assert.NoError(t, err)

// Assert
eligible := applicabilityManager.shouldRunApplicabilityScan([]coreutils.Technology{coreutils.Npm})
assert.False(t, eligible)
Expand Down Expand Up @@ -284,14 +242,9 @@ func TestExtractXrayDirectVulnerabilities(t *testing.T) {

func TestCreateConfigFile_VerifyFileWasCreated(t *testing.T) {
// Arrange
assert.NoError(t, rtutils.DownloadAnalyzerManagerIfNeeded())
scanner, err := NewAdvancedSecurityScanner(nil, &fakeServerDetails)
assert.NoError(t, err)
defer func() {
if scanner.scannerDirCleanupFunc != nil {
assert.NoError(t, scanner.scannerDirCleanupFunc())
}
}()
scanner, cleanUp := initJasTest(t)
defer cleanUp()

applicabilityManager := newApplicabilityScanManager(fakeBasicXrayResults, []string{"issueId_1_direct_dependency", "issueId_2_direct_dependency"}, scanner)

currWd, err := coreutils.GetWorkingDirectory()
Expand All @@ -313,14 +266,9 @@ func TestCreateConfigFile_VerifyFileWasCreated(t *testing.T) {

func TestParseResults_EmptyResults_AllCvesShouldGetUnknown(t *testing.T) {
// Arrange
assert.NoError(t, rtutils.DownloadAnalyzerManagerIfNeeded())
scanner, err := NewAdvancedSecurityScanner(nil, &fakeServerDetails)
assert.NoError(t, err)
defer func() {
if scanner.scannerDirCleanupFunc != nil {
assert.NoError(t, scanner.scannerDirCleanupFunc())
}
}()
scanner, cleanUp := initJasTest(t)
defer cleanUp()

applicabilityManager := newApplicabilityScanManager(fakeBasicXrayResults, mockDirectDependencies, scanner)
applicabilityManager.scanner.resultsFileName = filepath.Join("..", "..", "commands", "testdata", "applicability-scan", "empty-results.sarif")

Expand All @@ -337,14 +285,8 @@ func TestParseResults_EmptyResults_AllCvesShouldGetUnknown(t *testing.T) {

func TestParseResults_ApplicableCveExist(t *testing.T) {
// Arrange
assert.NoError(t, rtutils.DownloadAnalyzerManagerIfNeeded())
scanner, err := NewAdvancedSecurityScanner(nil, &fakeServerDetails)
assert.NoError(t, err)
defer func() {
if scanner.scannerDirCleanupFunc != nil {
assert.NoError(t, scanner.scannerDirCleanupFunc())
}
}()
scanner, cleanUp := initJasTest(t)
defer cleanUp()
applicabilityManager := newApplicabilityScanManager(fakeBasicXrayResults, mockDirectDependencies, scanner)
applicabilityManager.scanner.resultsFileName = filepath.Join("..", "..", "commands", "testdata", "applicability-scan", "applicable-cve-results.sarif")

Expand All @@ -360,14 +302,8 @@ func TestParseResults_ApplicableCveExist(t *testing.T) {

func TestParseResults_AllCvesNotApplicable(t *testing.T) {
// Arrange
assert.NoError(t, rtutils.DownloadAnalyzerManagerIfNeeded())
scanner, err := NewAdvancedSecurityScanner(nil, &fakeServerDetails)
assert.NoError(t, err)
defer func() {
if scanner.scannerDirCleanupFunc != nil {
assert.NoError(t, scanner.scannerDirCleanupFunc())
}
}()
scanner, cleanUp := initJasTest(t)
defer cleanUp()
applicabilityManager := newApplicabilityScanManager(fakeBasicXrayResults, mockDirectDependencies, scanner)
applicabilityManager.scanner.resultsFileName = filepath.Join("..", "..", "commands", "testdata", "applicability-scan", "no-applicable-cves-results.sarif")

Expand Down
18 changes: 11 additions & 7 deletions xray/audit/jas/iacscanner.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package jas

import (
"path/filepath"

"github.com/jfrog/jfrog-cli-core/v2/xray/utils"
"github.com/jfrog/jfrog-client-go/utils/log"
)
Expand All @@ -11,7 +13,7 @@ const (
)

type IacScanManager struct {
iacScannerResults []utils.IacOrSecretResult
iacScannerResults []utils.SourceCodeScanResult
scanner *AdvancedSecurityScanner
}

Expand All @@ -20,10 +22,10 @@ type IacScanManager struct {
// Running the analyzer manager executable.
// Parsing the analyzer manager results.
// Return values:
// []utils.IacOrSecretResult: a list of the iac violations that were found.
// []utils.SourceCodeScanResult: a list of the iac violations that were found.
// bool: true if the user is entitled to iac scan, false otherwise.
// error: An error object (if any).
func getIacScanResults(scanner *AdvancedSecurityScanner) (results []utils.IacOrSecretResult, err error) {
func getIacScanResults(scanner *AdvancedSecurityScanner) (results []utils.SourceCodeScanResult, err error) {
iacScanManager := newIacScanManager(scanner)
log.Info("Running IaC scanning...")
if err = iacScanManager.scanner.Run(iacScanManager); err != nil {
Expand All @@ -39,7 +41,7 @@ func getIacScanResults(scanner *AdvancedSecurityScanner) (results []utils.IacOrS

func newIacScanManager(scanner *AdvancedSecurityScanner) (manager *IacScanManager) {
return &IacScanManager{
iacScannerResults: []utils.IacOrSecretResult{},
iacScannerResults: []utils.SourceCodeScanResult{},
scanner: scanner,
}
}
Expand All @@ -52,8 +54,10 @@ func (iac *IacScanManager) Run(wd string) (err error) {
if err = iac.runAnalyzerManager(); err != nil {
return
}
var workingDirResults []utils.IacOrSecretResult
workingDirResults, err = getIacOrSecretsScanResults(scanner.resultsFileName, wd, false)
var workingDirResults []utils.SourceCodeScanResult
if workingDirResults, err = getSourceCodeScanResults(scanner.resultsFileName, wd, utils.IaC); err != nil {
return
}
iac.iacScannerResults = append(iac.iacScannerResults, workingDirResults...)
return
}
Expand Down Expand Up @@ -84,5 +88,5 @@ func (iac *IacScanManager) createConfigFile(currentWd string) error {
}

func (iac *IacScanManager) runAnalyzerManager() error {
return iac.scanner.analyzerManager.Exec(iac.scanner.configFileName, iacScanCommand, iac.scanner.serverDetails)
return iac.scanner.analyzerManager.Exec(iac.scanner.configFileName, iacScanCommand, filepath.Dir(iac.scanner.analyzerManager.AnalyzerManagerFullPath), iac.scanner.serverDetails)
}
Loading
Loading