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 tests for audit #965

Merged
merged 21 commits into from
Sep 21, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
90 changes: 90 additions & 0 deletions xray/commands/audit/jas/common_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package jas

import (
"testing"

"github.com/jfrog/jfrog-cli-core/v2/xray/utils"
"github.com/owenrumney/go-sarif/v2/sarif"
"github.com/stretchr/testify/assert"
)

func TestExcludeSuppressResults(t *testing.T) {
tests := []struct {
name string
sarifResults []*sarif.Result
expectedOutput []*sarif.Result
}{
{
sarifResults: []*sarif.Result{
utils.CreateResultWithOneLocation("", 0, 0, 0, 0, "snippet1", "ruleId1", "level1"),
utils.CreateResultWithOneLocation("", 0, 0, 0, 0, "snippet2", "ruleId2", "level2"),
},
expectedOutput: []*sarif.Result{
utils.CreateResultWithOneLocation("", 0, 0, 0, 0, "snippet1", "ruleId1", "level1"),
utils.CreateResultWithOneLocation("", 0, 0, 0, 0, "snippet2", "ruleId2", "level2"),
},
},
{
sarifResults: []*sarif.Result{
utils.CreateResultWithOneLocation("", 0, 0, 0, 0, "snippet1", "ruleId1", "level1").WithSuppression([]*sarif.Suppression{sarif.NewSuppression("")}),
utils.CreateResultWithOneLocation("", 0, 0, 0, 0, "snippet2", "ruleId2", "level2"),
},
expectedOutput: []*sarif.Result{
utils.CreateResultWithOneLocation("", 0, 0, 0, 0, "snippet2", "ruleId2", "level2"),
},
},
{
sarifResults: []*sarif.Result{
utils.CreateResultWithOneLocation("", 0, 0, 0, 0, "snippet1", "ruleId1", "level1").WithSuppression([]*sarif.Suppression{sarif.NewSuppression("")}),
utils.CreateResultWithOneLocation("", 0, 0, 0, 0, "snippet2", "ruleId2", "level2").WithSuppression([]*sarif.Suppression{sarif.NewSuppression("")}),
},
expectedOutput: []*sarif.Result{},
},
}

for _, test := range tests {
assert.Equal(t, test.expectedOutput, excludeSuppressResults(test.sarifResults))
}
}

func TestAddScoreToRunRules(t *testing.T) {

tests := []struct {
name string
sarifRun *sarif.Run
expectedOutput []*sarif.ReportingDescriptor
}{
{
sarifRun: utils.CreateRunWithDummyResults(
utils.CreateResultWithOneLocation("file1", 0, 0, 0, 0, "snippet", "rule1", "info"),
utils.CreateResultWithOneLocation("file2", 0, 0, 0, 0, "snippet", "rule1", "info"),
utils.CreateResultWithOneLocation("file", 0, 0, 0, 0, "snippet", "rule2", "warning"),
),
expectedOutput: []*sarif.ReportingDescriptor{
sarif.NewRule("rule1").WithProperties(sarif.Properties{"security-severity": "6.9"}),
sarif.NewRule("rule2").WithProperties(sarif.Properties{"security-severity": "6.9"}),
},
},
{
sarifRun: utils.CreateRunWithDummyResults(
utils.CreateResultWithOneLocation("file", 0, 0, 0, 0, "snippet", "rule1", "none"),
utils.CreateResultWithOneLocation("file", 0, 0, 0, 0, "snippet", "rule2", "note"),
utils.CreateResultWithOneLocation("file", 0, 0, 0, 0, "snippet", "rule3", "info"),
utils.CreateResultWithOneLocation("file", 0, 0, 0, 0, "snippet", "rule4", "warning"),
utils.CreateResultWithOneLocation("file", 0, 0, 0, 0, "snippet", "rule5", "error"),
),
expectedOutput: []*sarif.ReportingDescriptor{
sarif.NewRule("rule1").WithProperties(sarif.Properties{"security-severity": "0.0"}),
sarif.NewRule("rule2").WithProperties(sarif.Properties{"security-severity": "3.9"}),
sarif.NewRule("rule3").WithProperties(sarif.Properties{"security-severity": "6.9"}),
sarif.NewRule("rule4").WithProperties(sarif.Properties{"security-severity": "6.9"}),
sarif.NewRule("rule5").WithProperties(sarif.Properties{"security-severity": "8.9"}),
},
},
}

for _, test := range tests {
addScoreToRunRules(test.sarifRun)
assert.Equal(t, test.expectedOutput, test.sarifRun.Tool.Driver.Rules)
}
}
34 changes: 20 additions & 14 deletions xray/commands/audit/jas/sast/sastscanner.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package sast

import (
"fmt"

"github.com/jfrog/jfrog-cli-core/v2/xray/commands/audit/jas"
"github.com/jfrog/jfrog-cli-core/v2/xray/utils"
"github.com/jfrog/jfrog-client-go/utils/log"
Expand Down Expand Up @@ -47,7 +49,8 @@ func (ssm *SastScanManager) Run(wd string) (err error) {
if err != nil {
return
}
ssm.sastScannerResults = append(ssm.sastScannerResults, groupResultsByLocation(workingDirRuns)...)
groupResultsByLocation(workingDirRuns)
ssm.sastScannerResults = append(ssm.sastScannerResults, workingDirRuns...)
return
}

Expand All @@ -58,7 +61,7 @@ func (ssm *SastScanManager) runAnalyzerManager(wd string) error {
// In the Sast scanner, there can be multiple results with the same location.
// The only difference is that their CodeFlow values are different.
// We combine those under the same result location value
func groupResultsByLocation(sarifRuns []*sarif.Run) []*sarif.Run {
func groupResultsByLocation(sarifRuns []*sarif.Run) {
for _, sastRun := range sarifRuns {
locationToResult := map[string]*sarif.Result{}
for _, sastResult := range sastRun.Results {
Expand All @@ -71,25 +74,28 @@ func groupResultsByLocation(sarifRuns []*sarif.Run) []*sarif.Run {
}
sastRun.Results = maps.Values(locationToResult)
}
return sarifRuns
}

// In Sast there is only one location for each result
func getResultFileName(result *sarif.Result) string {
if len(result.Locations) > 0 {
return utils.GetLocationFileName(result.Locations[0])
func getResultLocationStr(result *sarif.Result) string {
if len(result.Locations) == 0 {
return ""
}
return ""
location := result.Locations[0]
return fmt.Sprintf("%s%d%d%d%d",
utils.GetLocationFileName(location),
utils.GetLocationStartLine(location),
utils.GetLocationStartColumn(location),
utils.GetLocationEndLine(location),
utils.GetLocationEndColumn(location))
}

// In Sast there is only one location for each result
func getResultStartLocationInFile(result *sarif.Result) string {
if len(result.Locations) > 0 {
return utils.GetStartLocationInFile(result.Locations[0])
func getResultRuleId(result *sarif.Result) string {
if result.RuleID == nil {
return ""
}
return ""
return *result.RuleID
}

func getResultId(result *sarif.Result) string {
return getResultFileName(result) + getResultStartLocationInFile(result) + utils.GetResultSeverity(result) + utils.GetResultMsgText(result)
return getResultRuleId(result) + utils.GetResultSeverity(result) + utils.GetResultMsgText(result) + getResultLocationStr(result)
}
92 changes: 90 additions & 2 deletions xray/commands/audit/jas/sast/sastscanner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"testing"

"github.com/jfrog/jfrog-cli-core/v2/xray/commands/audit/jas"
"github.com/jfrog/jfrog-cli-core/v2/xray/utils"
"github.com/owenrumney/go-sarif/v2/sarif"

"github.com/stretchr/testify/assert"
)
Expand Down Expand Up @@ -40,7 +42,7 @@ func TestSastParseResults_EmptyResults(t *testing.T) {
if assert.NoError(t, err) && assert.NotNil(t, sastScanManager.sastScannerResults) {
assert.Len(t, sastScanManager.sastScannerResults, 1)
assert.Empty(t, sastScanManager.sastScannerResults[0].Results)
sastScanManager.sastScannerResults = groupResultsByLocation(sastScanManager.sastScannerResults)
groupResultsByLocation(sastScanManager.sastScannerResults)
assert.Len(t, sastScanManager.sastScannerResults, 1)
assert.Empty(t, sastScanManager.sastScannerResults[0].Results)
}
Expand All @@ -61,8 +63,94 @@ func TestSastParseResults_ResultsContainIacViolations(t *testing.T) {
if assert.NoError(t, err) && assert.NotNil(t, sastScanManager.sastScannerResults) {
assert.Len(t, sastScanManager.sastScannerResults, 1)
assert.NotEmpty(t, sastScanManager.sastScannerResults[0].Results)
sastScanManager.sastScannerResults = groupResultsByLocation(sastScanManager.sastScannerResults)
groupResultsByLocation(sastScanManager.sastScannerResults)
// File has 4 results, 2 of them at the same location different codeFlow
assert.Len(t, sastScanManager.sastScannerResults[0].Results, 3)
}
}

func TestGroupResultsByLocation(t *testing.T) {
tests := []struct {
run *sarif.Run
expectedOutput *sarif.Run
}{
{
run: utils.CreateRunWithDummyResults(),
expectedOutput: utils.CreateRunWithDummyResults(),
},
{
// No similar groups at all
run: utils.CreateRunWithDummyResults(
utils.CreateResultWithOneLocation("file", 1, 2, 3, 4, "snippet", "rule1", "info"),
utils.CreateResultWithOneLocation("file", 1, 2, 3, 4, "snippet", "rule1", "note"),
utils.CreateResultWithOneLocation("file", 5, 6, 7, 8, "snippet", "rule1", "info"),
utils.CreateResultWithOneLocation("file2", 1, 2, 3, 4, "snippet", "rule1", "info").WithCodeFlows([]*sarif.CodeFlow{
utils.CreateCodeFlow(utils.CreateThreadFlow(
utils.CreateLocation("other", 0, 0, 0, 0, "other-snippet"),
utils.CreateLocation("file2", 1, 2, 3, 4, "snippet"),
)),
}),
utils.CreateResultWithOneLocation("file2", 1, 2, 3, 4, "snippet", "rule2", "info").WithCodeFlows([]*sarif.CodeFlow{
utils.CreateCodeFlow(utils.CreateThreadFlow(
utils.CreateLocation("other2", 1, 1, 1, 1, "other-snippet2"),
utils.CreateLocation("file2", 1, 2, 3, 4, "snippet"),
)),
}),
),
expectedOutput: utils.CreateRunWithDummyResults(
utils.CreateResultWithOneLocation("file", 1, 2, 3, 4, "snippet", "rule1", "info"),
utils.CreateResultWithOneLocation("file", 1, 2, 3, 4, "snippet", "rule1", "note"),
utils.CreateResultWithOneLocation("file", 5, 6, 7, 8, "snippet", "rule1", "info"),
utils.CreateResultWithOneLocation("file2", 1, 2, 3, 4, "snippet", "rule1", "info").WithCodeFlows([]*sarif.CodeFlow{
utils.CreateCodeFlow(utils.CreateThreadFlow(
utils.CreateLocation("other", 0, 0, 0, 0, "other-snippet"),
utils.CreateLocation("file2", 1, 2, 3, 4, "snippet"),
)),
}),
utils.CreateResultWithOneLocation("file2", 1, 2, 3, 4, "snippet", "rule2", "info").WithCodeFlows([]*sarif.CodeFlow{
utils.CreateCodeFlow(utils.CreateThreadFlow(
utils.CreateLocation("other2", 1, 1, 1, 1, "other-snippet2"),
utils.CreateLocation("file2", 1, 2, 3, 4, "snippet"),
)),
}),
),
},
{
// With similar groups
run: utils.CreateRunWithDummyResults(
utils.CreateResultWithOneLocation("file", 1, 2, 3, 4, "snippet", "rule1", "info").WithCodeFlows([]*sarif.CodeFlow{
utils.CreateCodeFlow(utils.CreateThreadFlow(
utils.CreateLocation("other", 0, 0, 0, 0, "other-snippet"),
utils.CreateLocation("file", 1, 2, 3, 4, "snippet"),
)),
}),
utils.CreateResultWithOneLocation("file", 1, 2, 3, 4, "snippet", "rule1", "info").WithCodeFlows([]*sarif.CodeFlow{
utils.CreateCodeFlow(utils.CreateThreadFlow(
utils.CreateLocation("other2", 1, 1, 1, 1, "other-snippet"),
utils.CreateLocation("file", 1, 2, 3, 4, "snippet"),
)),
}),
utils.CreateResultWithOneLocation("file", 5, 6, 7, 8, "snippet", "rule1", "info"),
utils.CreateResultWithOneLocation("file", 1, 2, 3, 4, "snippet", "rule1", "info"),
),
expectedOutput: utils.CreateRunWithDummyResults(
utils.CreateResultWithOneLocation("file", 1, 2, 3, 4, "snippet", "rule1", "info").WithCodeFlows([]*sarif.CodeFlow{
utils.CreateCodeFlow(utils.CreateThreadFlow(
utils.CreateLocation("other", 0, 0, 0, 0, "other-snippet"),
utils.CreateLocation("file", 1, 2, 3, 4, "snippet"),
)),
utils.CreateCodeFlow(utils.CreateThreadFlow(
utils.CreateLocation("other2", 1, 1, 1, 1, "other-snippet"),
utils.CreateLocation("file", 1, 2, 3, 4, "snippet"),
)),
}),
utils.CreateResultWithOneLocation("file", 5, 6, 7, 8, "snippet", "rule1", "info"),
),
},
}

for _, test := range tests {
groupResultsByLocation([]*sarif.Run{test.run})
assert.ElementsMatch(t, test.expectedOutput.Results, test.run.Results)
}
}
3 changes: 1 addition & 2 deletions xray/commands/audit/jas/secrets/secretsscanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,7 @@ func processSecretScanRuns(sarifRuns []*sarif.Run) []*sarif.Run {
// Hide discovered secrets value
for _, secretResult := range secretRun.Results {
for _, location := range secretResult.Locations {
secret := utils.GetLocationSnippetPointer(location)
utils.SetLocationSnippet(location, maskSecret(*secret))
utils.SetLocationSnippet(location, maskSecret(utils.GetLocationSnippet(location)))
}
}
}
Expand Down
Loading
Loading