Skip to content

Commit

Permalink
Missing context new status for CA (#153)
Browse files Browse the repository at this point in the history
  • Loading branch information
barv-jfrog authored Sep 17, 2024
1 parent c2d83db commit faa71b4
Show file tree
Hide file tree
Showing 13 changed files with 124 additions and 50 deletions.
18 changes: 9 additions & 9 deletions audit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -332,15 +332,15 @@ func TestXrayAuditMultiProjects(t *testing.T) {
assert.NoError(t, biutils.CopyDir(multiProject, tempDirPath, true, nil))
prevWd := securityTestUtils.ChangeWD(t, tempDirPath)
defer clientTests.ChangeDirAndAssert(t, prevWd)
workingDirsFlag := fmt.Sprintf("--working-dirs=%s, %s ,%s, %s",
workingDirsFlag := fmt.Sprintf("--working-dirs=%s, %s ,%s, %s, %s",
filepath.Join(tempDirPath, "package-managers", "maven", "maven"), filepath.Join(tempDirPath, "package-managers", "nuget", "single4.0"),
filepath.Join(tempDirPath, "package-managers", "python", "pip", "pip-project"), filepath.Join(tempDirPath, "jas", "jas"))
filepath.Join(tempDirPath, "package-managers", "python", "pip", "pip-project"), filepath.Join(tempDirPath, "jas", "jas"), filepath.Join(tempDirPath, "package-managers", "go", "missing-context"))
// Configure a new server named "default"
securityTestUtils.CreateJfrogHomeConfig(t, true)
defer securityTestUtils.CleanTestsHomeEnv()
output := securityTests.PlatformCli.WithoutCredentials().RunCliCmdWithOutput(t, "audit", "--format="+string(format.SimpleJson), workingDirsFlag)
securityTestUtils.VerifySimpleJsonScanResults(t, output, 0, 35, 0)
securityTestUtils.VerifySimpleJsonJasResults(t, output, 1, 9, 6, 3, 0, 25, 2)
securityTestUtils.VerifySimpleJsonJasResults(t, output, 1, 9, 6, 3, 0, 24, 2, 1)
}

func TestXrayAuditPipJson(t *testing.T) {
Expand Down Expand Up @@ -449,7 +449,7 @@ func TestXrayAuditNotEntitledForJas(t *testing.T) {
// Verify that scan results are printed
securityTestUtils.VerifySimpleJsonScanResults(t, output, 0, 8, 0)
// Verify that JAS results are not printed
securityTestUtils.VerifySimpleJsonJasResults(t, output, 0, 0, 0, 0, 0, 0, 0)
securityTestUtils.VerifySimpleJsonJasResults(t, output, 0, 0, 0, 0, 0, 0, 0, 0)
}

func getNoJasAuditMockCommand() components.Command {
Expand All @@ -471,24 +471,24 @@ func getNoJasAuditMockCommand() components.Command {
func TestXrayAuditJasSimpleJson(t *testing.T) {
output := testXrayAuditJas(t, securityTests.PlatformCli, filepath.Join("jas", "jas"), "3")
securityTestUtils.VerifySimpleJsonScanResults(t, output, 0, 8, 0)
securityTestUtils.VerifySimpleJsonJasResults(t, output, 1, 9, 6, 3, 1, 1, 2)
securityTestUtils.VerifySimpleJsonJasResults(t, output, 1, 9, 6, 3, 1, 1, 2, 0)
}

func TestXrayAuditJasSimpleJsonWithOneThread(t *testing.T) {
output := testXrayAuditJas(t, securityTests.PlatformCli, filepath.Join("jas", "jas"), "1")
securityTestUtils.VerifySimpleJsonScanResults(t, output, 0, 8, 0)
securityTestUtils.VerifySimpleJsonJasResults(t, output, 1, 9, 6, 3, 1, 1, 2)
securityTestUtils.VerifySimpleJsonJasResults(t, output, 1, 9, 6, 3, 1, 1, 2, 0)
}

func TestXrayAuditJasSimpleJsonWithConfig(t *testing.T) {
output := testXrayAuditJas(t, securityTests.PlatformCli, filepath.Join("jas", "jas-config"), "3")
securityTestUtils.VerifySimpleJsonJasResults(t, output, 0, 0, 1, 3, 1, 1, 2)
securityTestUtils.VerifySimpleJsonJasResults(t, output, 0, 0, 1, 3, 1, 1, 2, 0)
}

func TestXrayAuditJasNoViolationsSimpleJson(t *testing.T) {
output := testXrayAuditJas(t, securityTests.PlatformCli, filepath.Join("package-managers", "npm", "npm"), "3")
securityTestUtils.VerifySimpleJsonScanResults(t, output, 0, 1, 0)
securityTestUtils.VerifySimpleJsonJasResults(t, output, 0, 0, 0, 0, 0, 0, 1)
securityTestUtils.VerifySimpleJsonJasResults(t, output, 0, 0, 0, 0, 0, 0, 1, 0)
}

func testXrayAuditJas(t *testing.T, testCli *coreTests.JfrogCli, project string, threads string) string {
Expand Down Expand Up @@ -577,5 +577,5 @@ func TestAuditOnEmptyProject(t *testing.T) {
chdirCallback := clientTests.ChangeDirWithCallback(t, baseWd, tempDirPath)
defer chdirCallback()
output := securityTests.PlatformCli.WithoutCredentials().RunCliCmdWithOutput(t, "audit", "--format="+string(format.SimpleJson))
securityTestUtils.VerifySimpleJsonJasResults(t, output, 0, 0, 0, 0, 0, 0, 0)
securityTestUtils.VerifySimpleJsonJasResults(t, output, 0, 0, 0, 0, 0, 0, 0, 0)
}
2 changes: 1 addition & 1 deletion jas/analyzermanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import (
const (
ApplicabilityFeatureId = "contextual_analysis"
AnalyzerManagerZipName = "analyzerManager.zip"
defaultAnalyzerManagerVersion = "1.8.14"
defaultAnalyzerManagerVersion = "1.8.15"
analyzerManagerDownloadPath = "xsc-gen-exe-analyzer-manager-local/v1"
analyzerManagerDirName = "analyzerManager"
analyzerManagerExecutableName = "analyzerManager"
Expand Down
2 changes: 1 addition & 1 deletion jas/applicability/applicabilitymanager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ func TestParseResults_NewApplicabilityStatuses(t *testing.T) {
name: "new applicability statuses",
fileName: "new_ca_status.sarif",
expectedResults: 5,
expectedApplicabilityStatuses: []string{"applicable", "undetermined", "not_covered", "not_applicable"},
expectedApplicabilityStatuses: []string{"applicable", "undetermined", "not_covered", "missing_context", "not_applicable"},
},
}

Expand Down
14 changes: 14 additions & 0 deletions tests/testdata/other/applicability-scan/new_ca_status.sarif
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,20 @@
"shortDescription": {
"text": "Scanner for CVE-2020-1747"
}
},
{
"id": "applic_CVE-2020-1751",
"name": "CVE-2020-1751",
"properties": {
"applicability": "missing_context"
},
"fullDescription": {
"text": "The scanner checks whether any of the following vulnerable functions are called:\n\n- `yaml.full_load()`\n- `yaml.load()` only unsafe calls (without specifying `SafeLoader` as the `Loader`class).",
"markdown": "The scanner checks whether any of the following vulnerable functions are called:\n\n- `yaml.full_load()`\n- `yaml.load()` only unsafe calls (without specifying `SafeLoader` as the `Loader`class)."
},
"shortDescription": {
"text": "Scanner for CVE-2020-1751"
}
},
{
"id": "applic_CVE-2020-7788",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module missing_context

go 1.22

require github.com/hashicorp/consul v1.9.1


Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
github.com/hashicorp/consul v1.9.1/go.mod h1:RQlaP4r7KdNLaPDuihkvghhdvZVOuVlUhlz7HtvC1UI=
7 changes: 5 additions & 2 deletions tests/utils/test_validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,14 @@ func VerifySimpleJsonScanResults(t *testing.T, content string, minViolations, mi
}

func VerifySimpleJsonJasResults(t *testing.T, content string, minSastViolations, minIacViolations, minSecrets,
minApplicable, minUndetermined, minNotCovered, minNotApplicable int) {
minApplicable, minUndetermined, minNotCovered, minNotApplicable, minMissingContext int) {
var results formats.SimpleJsonResults
err := json.Unmarshal([]byte(content), &results)
if assert.NoError(t, err) {
assert.GreaterOrEqual(t, len(results.Sast), minSastViolations, "Found less sast then expected")
assert.GreaterOrEqual(t, len(results.Secrets), minSecrets, "Found less secrets then expected")
assert.GreaterOrEqual(t, len(results.Iacs), minIacViolations, "Found less IaC then expected")
var applicableResults, undeterminedResults, notCoveredResults, notApplicableResults int
var applicableResults, undeterminedResults, notCoveredResults, notApplicableResults, missingContextResults int
for _, vuln := range results.Vulnerabilities {
switch vuln.Applicable {
case string(jasutils.NotApplicable):
Expand All @@ -84,11 +84,14 @@ func VerifySimpleJsonJasResults(t *testing.T, content string, minSastViolations,
notCoveredResults++
case string(jasutils.ApplicabilityUndetermined):
undeterminedResults++
case string(jasutils.MissingContext):
missingContextResults++
}
}
assert.GreaterOrEqual(t, applicableResults, minApplicable, "Found less applicableResults then expected")
assert.GreaterOrEqual(t, undeterminedResults, minUndetermined, "Found less undeterminedResults then expected")
assert.GreaterOrEqual(t, notCoveredResults, minNotCovered, "Found less notCoveredResults then expected")
assert.GreaterOrEqual(t, notApplicableResults, minNotApplicable, "Found less notApplicableResults then expected")
assert.GreaterOrEqual(t, missingContextResults, minMissingContext, "Found less missingContextResults then expected")
}
}
10 changes: 7 additions & 3 deletions utils/jasutils/jasutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const (
NotApplicable ApplicabilityStatus = "Not Applicable"
ApplicabilityUndetermined ApplicabilityStatus = "Undetermined"
NotCovered ApplicabilityStatus = "Not Covered"
MissingContext ApplicabilityStatus = "Missing Context"
NotScanned ApplicabilityStatus = ""
)

Expand Down Expand Up @@ -63,6 +64,8 @@ func ConvertToApplicabilityStatus(status string) ApplicabilityStatus {
return ApplicabilityUndetermined
case NotCovered.String():
return NotCovered
case MissingContext.String():
return MissingContext
default:
return NotScanned
}
Expand All @@ -77,9 +80,10 @@ func ApplicabilityRuleIdToCve(sarifRuleId string) string {
}

var applicableMapToScore = map[string]int{
"Applicable": 4,
"ApplicabilityUndetermined": 3,
"NotScanned": 2,
"Applicable": 5,
"ApplicabilityUndetermined": 4,
"NotScanned": 3,
"MissingContext": 2,
"NotCovered": 1,
"NotApplicable": 0,
}
Expand Down
12 changes: 12 additions & 0 deletions utils/resultstable.go
Original file line number Diff line number Diff line change
Expand Up @@ -1048,6 +1048,8 @@ func getApplicabilityStatusFromRule(rule *sarif.ReportingDescriptor) jasutils.Ap
return jasutils.NotApplicable
case "applicable":
return jasutils.Applicable
case "missing_context":
return jasutils.MissingContext
}
}
return ""
Expand All @@ -1056,13 +1058,15 @@ func getApplicabilityStatusFromRule(rule *sarif.ReportingDescriptor) jasutils.Ap
// If we don't get any statues it means the applicability scanner didn't run -> final value is not scanned
// If at least one cve is applicable -> final value is applicable
// Else if at least one cve is undetermined -> final value is undetermined
// Else if at least one cve is missing context -> final value is missing context
// Else if all cves are not covered -> final value is not covered
// Else (case when all cves aren't applicable) -> final value is not applicable
func getFinalApplicabilityStatus(applicabilityStatuses []jasutils.ApplicabilityStatus) jasutils.ApplicabilityStatus {
if len(applicabilityStatuses) == 0 {
return jasutils.NotScanned
}
foundUndetermined := false
foundMissingContext := false
foundNotCovered := false
for _, status := range applicabilityStatuses {
if status == jasutils.Applicable {
Expand All @@ -1071,15 +1075,23 @@ func getFinalApplicabilityStatus(applicabilityStatuses []jasutils.ApplicabilityS
if status == jasutils.ApplicabilityUndetermined {
foundUndetermined = true
}
if status == jasutils.MissingContext {
foundMissingContext = true
}
if status == jasutils.NotCovered {
foundNotCovered = true
}

}
if foundUndetermined {
return jasutils.ApplicabilityUndetermined
}
if foundMissingContext {
return jasutils.MissingContext
}
if foundNotCovered {
return jasutils.NotCovered
}

return jasutils.NotApplicable
}
54 changes: 41 additions & 13 deletions utils/resultstable_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,18 @@ func TestGetApplicableCveValue(t *testing.T) {
expectedResult: jasutils.Applicable,
expectedCves: []formats.CveRow{{Id: "testCve2", Applicability: &formats.Applicability{Status: jasutils.Applicable.String()}}},
},
{
name: "missing context cve",
scanResults: &ExtendedScanResults{
ApplicabilityScanResults: []*sarif.Run{
sarifutils.CreateRunWithDummyResultAndRuleProperties(sarifutils.CreateDummyPassingResult("applic_testCve1"), []string{"applicability"}, []string{"missing_context"}),
},
EntitledForJas: true,
},
cves: []services.Cve{{Id: "testCve1"}},
expectedResult: jasutils.MissingContext,
expectedCves: []formats.CveRow{{Id: "testCve1", Applicability: &formats.Applicability{Status: jasutils.MissingContext.String()}}},
},
{
name: "undetermined cve",
scanResults: &ExtendedScanResults{
Expand Down Expand Up @@ -685,13 +697,15 @@ func TestGetApplicableCveValue(t *testing.T) {
sarifutils.CreateRunWithDummyResultAndRuleProperties(sarifutils.CreateDummyPassingResult("applic_testCve1"), []string{"applicability"}, []string{"applicable"}),
sarifutils.CreateRunWithDummyResultAndRuleProperties(sarifutils.CreateDummyPassingResult("applic_testCve2"), []string{"applicability"}, []string{"not_applicable"}),
sarifutils.CreateRunWithDummyResultAndRuleProperties(sarifutils.CreateDummyPassingResult("applic_testCve3"), []string{"applicability"}, []string{"not_covered"}),
sarifutils.CreateRunWithDummyResultAndRuleProperties(sarifutils.CreateDummyPassingResult("applic_testCve4"), []string{"applicability"}, []string{"missing_context"}),
},
EntitledForJas: true},
cves: []services.Cve{{Id: "testCve1"}, {Id: "testCve2"}, {Id: "testCve3"}},
cves: []services.Cve{{Id: "testCve1"}, {Id: "testCve2"}, {Id: "testCve3"}, {Id: "testCve4"}},
expectedResult: jasutils.Applicable,
expectedCves: []formats.CveRow{{Id: "testCve1", Applicability: &formats.Applicability{Status: jasutils.Applicable.String()}},
{Id: "testCve2", Applicability: &formats.Applicability{Status: jasutils.NotApplicable.String()}},
{Id: "testCve2", Applicability: &formats.Applicability{Status: jasutils.NotCovered.String()}},
{Id: "testCve2", Applicability: &formats.Applicability{Status: jasutils.MissingContext.String()}},
},
},
{
Expand All @@ -709,16 +723,16 @@ func TestGetApplicableCveValue(t *testing.T) {
},
},
{
name: "new scan statuses - undetermined wins not covered",
name: "new scan statuses - undetermined wins missing-context",
scanResults: &ExtendedScanResults{
ApplicabilityScanResults: []*sarif.Run{
sarifutils.CreateRunWithDummyResultAndRuleProperties(sarifutils.CreateDummyPassingResult("applic_testCve1"), []string{"applicability"}, []string{"not_covered"}),
sarifutils.CreateRunWithDummyResultAndRuleProperties(sarifutils.CreateDummyPassingResult("applic_testCve1"), []string{"applicability"}, []string{"missing_context"}),
sarifutils.CreateRunWithDummyResultAndRuleProperties(sarifutils.CreateDummyPassingResult("applic_testCve2"), []string{"applicability"}, []string{"undetermined"}),
},
EntitledForJas: true},
cves: []services.Cve{{Id: "testCve1"}, {Id: "testCve2"}},
expectedResult: jasutils.ApplicabilityUndetermined,
expectedCves: []formats.CveRow{{Id: "testCve1", Applicability: &formats.Applicability{Status: jasutils.NotCovered.String()}},
expectedCves: []formats.CveRow{{Id: "testCve1", Applicability: &formats.Applicability{Status: jasutils.MissingContext.String()}},
{Id: "testCve2", Applicability: &formats.Applicability{Status: jasutils.ApplicabilityUndetermined.String()}},
},
},
Expand All @@ -735,6 +749,20 @@ func TestGetApplicableCveValue(t *testing.T) {
{Id: "testCve2", Applicability: &formats.Applicability{Status: jasutils.ApplicabilityUndetermined.String(), UndeterminedReason: "however"}},
},
},
{
name: "new scan statuses - missing context wins not covered",
scanResults: &ExtendedScanResults{
ApplicabilityScanResults: []*sarif.Run{
sarifutils.CreateRunWithDummyResultAndRuleProperties(sarifutils.CreateDummyPassingResult("applic_testCve1"), []string{"applicability"}, []string{"missing_context"}),
sarifutils.CreateRunWithDummyResultAndRuleProperties(sarifutils.CreateDummyPassingResult("applic_testCve2"), []string{"applicability"}, []string{"not_covered"}),
},
EntitledForJas: true},
cves: []services.Cve{{Id: "testCve1"}, {Id: "testCve2"}},
expectedResult: jasutils.MissingContext,
expectedCves: []formats.CveRow{{Id: "testCve1", Applicability: &formats.Applicability{Status: jasutils.MissingContext.String()}},
{Id: "testCve2", Applicability: &formats.Applicability{Status: jasutils.NotCovered.String()}},
},
},
}

for _, testCase := range testCases {
Expand Down Expand Up @@ -969,7 +997,7 @@ func TestPrepareIac(t *testing.T) {
{
SeverityDetails: formats.SeverityDetails{
Severity: "High",
SeverityNumValue: 17,
SeverityNumValue: 21,
},
Finding: "other iac finding",
Location: formats.Location{
Expand All @@ -984,7 +1012,7 @@ func TestPrepareIac(t *testing.T) {
{
SeverityDetails: formats.SeverityDetails{
Severity: "Medium",
SeverityNumValue: 14,
SeverityNumValue: 17,
},
Finding: "iac finding",
Location: formats.Location{
Expand All @@ -999,7 +1027,7 @@ func TestPrepareIac(t *testing.T) {
{
SeverityDetails: formats.SeverityDetails{
Severity: "Medium",
SeverityNumValue: 14,
SeverityNumValue: 17,
},
Finding: "iac finding",
Location: formats.Location{
Expand Down Expand Up @@ -1066,7 +1094,7 @@ func TestPrepareSecrets(t *testing.T) {
{
SeverityDetails: formats.SeverityDetails{
Severity: "Low",
SeverityNumValue: 11,
SeverityNumValue: 13,
},
Finding: "other secret finding",
Location: formats.Location{
Expand All @@ -1081,7 +1109,7 @@ func TestPrepareSecrets(t *testing.T) {
{
SeverityDetails: formats.SeverityDetails{
Severity: "Medium",
SeverityNumValue: 14,
SeverityNumValue: 17,
},
Finding: "secret finding",
Location: formats.Location{
Expand All @@ -1096,7 +1124,7 @@ func TestPrepareSecrets(t *testing.T) {
{
SeverityDetails: formats.SeverityDetails{
Severity: "Medium",
SeverityNumValue: 14,
SeverityNumValue: 17,
},
Finding: "secret finding",
Location: formats.Location{
Expand Down Expand Up @@ -1172,7 +1200,7 @@ func TestPrepareSast(t *testing.T) {
{
SeverityDetails: formats.SeverityDetails{
Severity: "High",
SeverityNumValue: 17,
SeverityNumValue: 21,
},
Finding: "other sast finding",
Location: formats.Location{
Expand All @@ -1187,7 +1215,7 @@ func TestPrepareSast(t *testing.T) {
{
SeverityDetails: formats.SeverityDetails{
Severity: "Medium",
SeverityNumValue: 14,
SeverityNumValue: 17,
},
Finding: "sast finding",
Location: formats.Location{
Expand Down Expand Up @@ -1240,7 +1268,7 @@ func TestPrepareSast(t *testing.T) {
{
SeverityDetails: formats.SeverityDetails{
Severity: "Medium",
SeverityNumValue: 14,
SeverityNumValue: 17,
},
Finding: "sast finding",
Location: formats.Location{
Expand Down
Loading

0 comments on commit faa71b4

Please sign in to comment.