From c9f4fe58aa312030d211c198ec927e275949cbf4 Mon Sep 17 00:00:00 2001 From: barv Date: Tue, 13 Aug 2024 15:49:17 +0300 Subject: [PATCH 01/32] Token Validation feature --- cli/docs/flags.go | 22 ++++----- cli/scancommands.go | 10 ++++- commands/audit/audit.go | 5 ++- commands/scan/scan.go | 17 ++++--- formats/conversion.go | 10 +++-- formats/sarifutils/sarifutils.go | 19 ++++++++ formats/sarifutils/test_sarifutils.go | 14 ++++++ formats/simplejsonapi.go | 2 + formats/table.go | 10 +++-- go.mod | 2 +- go.sum | 4 +- jas/analyzermanager.go | 2 + jas/common.go | 23 +++++++++- jas/common_test.go | 2 +- jas/runner/jasrunner_test.go | 6 +-- utils/jasutils/jasutils.go | 12 +++++ utils/results.go | 1 + utils/resultstable.go | 31 ++++++++----- utils/resultstable_test.go | 65 +++++++++++++++++++++++++++ utils/utils.go | 13 +++--- 20 files changed, 216 insertions(+), 54 deletions(-) diff --git a/cli/docs/flags.go b/cli/docs/flags.go index 3297c36a..e1d83b9f 100644 --- a/cli/docs/flags.go +++ b/cli/docs/flags.go @@ -106,6 +106,7 @@ const ( buildPrefix = "build-" BuildVuln = buildPrefix + Vuln ScanVuln = scanPrefix + Vuln + SecretValidation = "validate-secrets" // Unique audit flags auditPrefix = "audit-" @@ -146,13 +147,13 @@ var commandFlags = map[string][]string{ url, user, password, accessToken, ServerId, Project, BuildVuln, OutputFormat, Fail, ExtendedTable, Rescan, }, DockerScan: { - ServerId, Project, Watches, RepoPath, Licenses, OutputFormat, Fail, ExtendedTable, BypassArchiveLimits, MinSeverity, FixableOnly, ScanVuln, + ServerId, Project, Watches, RepoPath, Licenses, OutputFormat, Fail, ExtendedTable, BypassArchiveLimits, MinSeverity, FixableOnly, ScanVuln, SecretValidation, }, Audit: { url, user, password, accessToken, ServerId, InsecureTls, Project, Watches, RepoPath, Licenses, OutputFormat, ExcludeTestDeps, useWrapperAudit, DepType, RequirementsFile, Fail, ExtendedTable, WorkingDirs, ExclusionsAudit, Mvn, Gradle, Npm, Pnpm, Yarn, Go, Nuget, Pip, Pipenv, Poetry, MinSeverity, FixableOnly, ThirdPartyContextualAnalysis, Threads, - Sca, Iac, Sast, Secrets, WithoutCA, ScanVuln, + Sca, Iac, Sast, Secrets, WithoutCA, ScanVuln, SecretValidation, }, CurationAudit: { CurationOutput, WorkingDirs, Threads, RequirementsFile, @@ -199,14 +200,15 @@ var flagsMap = map[string]components.Flag{ Stream: components.NewStringFlag(Stream, fmt.Sprintf("Xray DBSync V3 stream, Possible values are: %s.", offlineupdate.NewValidStreams().GetValidStreamsString())), Periodic: components.NewBoolFlag(Periodic, fmt.Sprintf("Set to true to get the Xray DBSync V3 Periodic Package (Use with %s flag).", Stream)), // Scan flags - SpecFlag: components.NewStringFlag(SpecFlag, "Path to a File Spec."), - scanRecursive: components.NewBoolFlag(Recursive, "Set to false if you do not wish to collect artifacts in sub-folders to be scanned by Xray.", components.WithBoolDefaultValue(true)), - scanRegexp: components.NewBoolFlag(RegexpFlag, "Set to true to use a regular expression instead of wildcards expression to collect files to scan."), - scanAnt: components.NewBoolFlag(AntFlag, "Set to true to use an ant pattern instead of wildcards expression to collect files to scan."), - Project: components.NewStringFlag(Project, "JFrog Artifactory project key."), - Watches: components.NewStringFlag(Watches, "A comma-separated list of Xray watches, to determine Xray's violations creation."), - RepoPath: components.NewStringFlag(RepoPath, "Target repo path, to enable Xray to determine watches accordingly."), - Licenses: components.NewBoolFlag(Licenses, "Set to true if you'd like to receive licenses from Xray scanning."), + SpecFlag: components.NewStringFlag(SpecFlag, "Path to a File Spec."), + scanRecursive: components.NewBoolFlag(Recursive, "Set to false if you do not wish to collect artifacts in sub-folders to be scanned by Xray.", components.WithBoolDefaultValue(true)), + scanRegexp: components.NewBoolFlag(RegexpFlag, "Set to true to use a regular expression instead of wildcards expression to collect files to scan."), + scanAnt: components.NewBoolFlag(AntFlag, "Set to true to use an ant pattern instead of wildcards expression to collect files to scan."), + Project: components.NewStringFlag(Project, "JFrog Artifactory project key."), + Watches: components.NewStringFlag(Watches, "A comma-separated list of Xray watches, to determine Xray's violations creation."), + RepoPath: components.NewStringFlag(RepoPath, "Target repo path, to enable Xray to determine watches accordingly."), + Licenses: components.NewBoolFlag(Licenses, "Set to true if you'd like to receive licenses from Xray scanning."), + SecretValidation: components.NewBoolFlag(SecretValidation, "Set to true if you want exposures scanner to validate api tokens"), OutputFormat: components.NewStringFlag( OutputFormat, "Defines the output format of the command. Acceptable values are: table, json, simple-json and sarif. Note: the json format doesn't include information about scans that are included as part of the Advanced Security package.", diff --git a/cli/scancommands.go b/cli/scancommands.go index 86e63a15..c32fecec 100644 --- a/cli/scancommands.go +++ b/cli/scancommands.go @@ -387,6 +387,11 @@ func AuditCmd(c *components.Context) error { return pluginsCommon.PrintHelpAndReturnError(fmt.Sprintf("flag '--%s' cannot be used without '--%s'", flags.WithoutCA, flags.Sca), c) } + if c.GetBoolFlagValue(flags.SecretValidation) && !c.GetBoolFlagValue(flags.Secrets) { + // No secrets flag but secret validation is provided, error + return pluginsCommon.PrintHelpAndReturnError(fmt.Sprintf("flag '--%s' cannot be used without '--%s'", flags.SecretValidation, flags.Secrets), c) + } + allSubScans := utils.GetAllSupportedScans() subScans := []utils.SubScanType{} for _, subScan := range allSubScans { @@ -411,7 +416,7 @@ func AuditCmd(c *components.Context) error { func shouldAddSubScan(subScan utils.SubScanType, c *components.Context) bool { return c.GetBoolFlagValue(subScan.String()) || - (subScan == utils.ContextualAnalysisScan && c.GetBoolFlagValue(flags.Sca) && !c.GetBoolFlagValue(flags.WithoutCA)) + (subScan == utils.ContextualAnalysisScan && c.GetBoolFlagValue(flags.Sca) && !c.GetBoolFlagValue(flags.WithoutCA)) || (subScan == utils.SecretTokenValidationScan && c.GetBoolFlagValue(flags.Secrets) && c.GetBoolFlagValue(flags.SecretValidation)) } func reportErrorIfExists(err error, auditCmd *audit.AuditCommand) { @@ -604,7 +609,8 @@ func DockerScan(c *components.Context, image string) error { SetBypassArchiveLimits(c.GetBoolFlagValue(flags.BypassArchiveLimits)). SetFixableOnly(c.GetBoolFlagValue(flags.FixableOnly)). SetMinSeverityFilter(minSeverity). - SetThreads(threads) + SetThreads(threads). + SetSecretValidation(c.GetBoolFlagValue(flags.SecretValidation)) if c.GetStringFlagValue(flags.Watches) != "" { containerScanCommand.SetWatches(splitByCommaAndTrim(c.GetStringFlagValue(flags.Watches))) } diff --git a/commands/audit/audit.go b/commands/audit/audit.go index 1a5b00f7..9a467ac3 100644 --- a/commands/audit/audit.go +++ b/commands/audit/audit.go @@ -3,6 +3,7 @@ package audit import ( "errors" "fmt" + "golang.org/x/exp/slices" "os" jfrogappsconfig "github.com/jfrog/jfrog-apps-config/go" @@ -198,8 +199,8 @@ func RunAudit(auditParams *AuditParams) (results *utils.Results, err error) { if err != nil { return } + results.ExtendedScanResults.SecretValidation = jas.CheckForSecretValidation(xrayManager, auditParams.xrayVersion, slices.Contains(auditParams.AuditBasicParams.ScansToPerform(), utils.SecretTokenValidationScan)) results.MultiScanId = auditParams.commonGraphScanParams.MultiScanId - auditParallelRunner := utils.CreateSecurityParallelRunner(auditParams.threads) auditParallelRunner.ErrWg.Add(1) jfrogAppsConfig, err := jas.CreateJFrogAppsConfig(auditParams.workingDirs) @@ -264,7 +265,7 @@ func downloadAnalyzerManagerAndRunScanners(auditParallelRunner *utils.SecurityPa if err = jas.DownloadAnalyzerManagerIfNeeded(threadId); err != nil { return fmt.Errorf("%s failed to download analyzer manager: %s", clientutils.GetLogMsgPrefix(threadId, false), err.Error()) } - scanner, err = jas.CreateJasScanner(scanner, jfrogAppsConfig, serverDetails, jas.GetAnalyzerManagerXscEnvVars(auditParams.commonGraphScanParams.MultiScanId, scanResults.GetScaScannedTechnologies()...), auditParams.Exclusions()...) + scanner, err = jas.CreateJasScanner(scanner, jfrogAppsConfig, serverDetails, jas.GetAnalyzerManagerXscEnvVars(auditParams.commonGraphScanParams.MultiScanId, scanResults.ExtendedScanResults.SecretValidation, scanResults.GetScaScannedTechnologies()...), auditParams.Exclusions()...) if err != nil { return fmt.Errorf("failed to create jas scanner: %s", err.Error()) } diff --git a/commands/scan/scan.go b/commands/scan/scan.go index 3accf686..8ac51165 100644 --- a/commands/scan/scan.go +++ b/commands/scan/scan.go @@ -70,6 +70,7 @@ type ScanCommand struct { includeLicenses bool fail bool printExtendedTable bool + validateSecrets bool bypassArchiveLimits bool fixableOnly bool progress ioUtils.ProgressMgr @@ -81,6 +82,11 @@ func (scanCmd *ScanCommand) SetMinSeverityFilter(minSeverityFilter severityutils return scanCmd } +func (scanCmd *ScanCommand) SetSecretValidation(validateSecrets bool) *ScanCommand { + scanCmd.validateSecrets = validateSecrets + return scanCmd +} + func (scanCmd *ScanCommand) SetFixableOnly(fixable bool) *ScanCommand { scanCmd.fixableOnly = fixable return scanCmd @@ -208,6 +214,7 @@ func (scanCmd *ScanCommand) RunAndRecordResults(recordResFunc func(scanResults * scanResults.XrayVersion = xrayVersion scanResults.ExtendedScanResults.EntitledForJas, err = jas.IsEntitledForJas(xrayManager, xrayVersion) + scanResults.ExtendedScanResults.SecretValidation = jas.CheckForSecretValidation(xrayManager, xrayVersion, scanCmd.validateSecrets) errGroup := new(errgroup.Group) if scanResults.ExtendedScanResults.EntitledForJas { // Download (if needed) the analyzer manager in a background routine. @@ -266,7 +273,7 @@ func (scanCmd *ScanCommand) RunAndRecordResults(recordResFunc func(scanResults * jasScanProducerErrors := make([][]formats.SimpleJsonError, threads) // Start walking on the filesystem to "produce" files that match the given pattern // while the consumer uses the indexer to index those files. - scanCmd.prepareScanTasks(fileProducerConsumer, indexedFileProducerConsumer, &JasScanProducerConsumer, scanResults.ExtendedScanResults.EntitledForJas, resultsArr, fileProducerErrors, indexedFileProducerErrors, jasScanProducerErrors, fileCollectingErrorsQueue, xrayVersion) + scanCmd.prepareScanTasks(fileProducerConsumer, indexedFileProducerConsumer, &JasScanProducerConsumer, scanResults.ExtendedScanResults.EntitledForJas, scanResults.ExtendedScanResults.SecretValidation, resultsArr, fileProducerErrors, indexedFileProducerErrors, jasScanProducerErrors, fileCollectingErrorsQueue, xrayVersion) scanCmd.performScanTasks(fileProducerConsumer, indexedFileProducerConsumer, &JasScanProducerConsumer) // Handle results @@ -338,14 +345,14 @@ func (scanCmd *ScanCommand) CommandName() string { return "xr_scan" } -func (scanCmd *ScanCommand) prepareScanTasks(fileProducer, indexedFileProducer parallel.Runner, jasFileProducerConsumer *utils.SecurityParallelRunner, entitledForJas bool, resultsArr [][]*ScanInfo, fileErrors, indexedFileErrors, jasErrors [][]formats.SimpleJsonError, fileCollectingErrorsQueue *clientutils.ErrorsQueue, xrayVersion string) { +func (scanCmd *ScanCommand) prepareScanTasks(fileProducer, indexedFileProducer parallel.Runner, jasFileProducerConsumer *utils.SecurityParallelRunner, entitledForJas bool, validateSecrets bool, resultsArr [][]*ScanInfo, fileErrors, indexedFileErrors, jasErrors [][]formats.SimpleJsonError, fileCollectingErrorsQueue *clientutils.ErrorsQueue, xrayVersion string) { go func() { defer fileProducer.Done() // Iterate over file-spec groups and produce indexing tasks. // When encountering an error, log and move to next group. specFiles := scanCmd.spec.Files for i := range specFiles { - artifactHandlerFunc := scanCmd.createIndexerHandlerFunc(&specFiles[i], entitledForJas, indexedFileProducer, jasFileProducerConsumer, resultsArr, fileErrors, indexedFileErrors, jasErrors, xrayVersion) + artifactHandlerFunc := scanCmd.createIndexerHandlerFunc(&specFiles[i], entitledForJas, validateSecrets, indexedFileProducer, jasFileProducerConsumer, resultsArr, fileErrors, indexedFileErrors, jasErrors, xrayVersion) taskHandler := getAddTaskToProducerFunc(fileProducer, artifactHandlerFunc) err := collectFilesForIndexing(specFiles[i], taskHandler) @@ -357,7 +364,7 @@ func (scanCmd *ScanCommand) prepareScanTasks(fileProducer, indexedFileProducer p }() } -func (scanCmd *ScanCommand) createIndexerHandlerFunc(file *spec.File, entitledForJas bool, indexedFileProducer parallel.Runner, jasFileProducerConsumer *utils.SecurityParallelRunner, resultsArr [][]*ScanInfo, fileErrors, indexedFileErrors, jasErrors [][]formats.SimpleJsonError, xrayVersion string) FileContext { +func (scanCmd *ScanCommand) createIndexerHandlerFunc(file *spec.File, entitledForJas bool, validateSecrets bool, indexedFileProducer parallel.Runner, jasFileProducerConsumer *utils.SecurityParallelRunner, resultsArr [][]*ScanInfo, fileErrors, indexedFileErrors, jasErrors [][]formats.SimpleJsonError, xrayVersion string) FileContext { return func(filePath string) parallel.TaskFunc { return func(threadId int) (err error) { logMsgPrefix := clientutils.GetLogMsgPrefix(threadId, false) @@ -425,7 +432,7 @@ func (scanCmd *ScanCommand) createIndexerHandlerFunc(file *spec.File, entitledFo indexedFileErrors[threadId] = append(indexedFileErrors[threadId], formats.SimpleJsonError{FilePath: filePath, ErrorMessage: err.Error()}) } scanner := &jas.JasScanner{} - scanner, err = jas.CreateJasScanner(scanner, jfrogAppsConfig, scanCmd.serverDetails, jas.GetAnalyzerManagerXscEnvVars("", techutils.Technology(graphScanResults.ScannedPackageType))) + scanner, err = jas.CreateJasScanner(scanner, jfrogAppsConfig, scanCmd.serverDetails, jas.GetAnalyzerManagerXscEnvVars("", validateSecrets, techutils.Technology(graphScanResults.ScannedPackageType))) if err != nil { log.Error(fmt.Sprintf("failed to create jas scanner: %s", err.Error())) indexedFileErrors[threadId] = append(indexedFileErrors[threadId], formats.SimpleJsonError{FilePath: filePath, ErrorMessage: err.Error()}) diff --git a/formats/conversion.go b/formats/conversion.go index 8a602869..95c33268 100644 --- a/formats/conversion.go +++ b/formats/conversion.go @@ -144,10 +144,12 @@ func ConvertToOperationalRiskViolationScanTableRow(rows []OperationalRiskViolati func ConvertToSecretsTableRow(rows []SourceCodeRow) (tableRows []secretsTableRow) { for i := range rows { tableRows = append(tableRows, secretsTableRow{ - severity: rows[i].Severity, - file: rows[i].File, - lineColumn: strconv.Itoa(rows[i].StartLine) + ":" + strconv.Itoa(rows[i].StartColumn), - secret: rows[i].Snippet, + severity: rows[i].Severity, + file: rows[i].File, + lineColumn: strconv.Itoa(rows[i].StartLine) + ":" + strconv.Itoa(rows[i].StartColumn), + secret: rows[i].Snippet, + tokenValidation: rows[i].TokenValidation, + metadata: rows[i].Metadata, }) } return diff --git a/formats/sarifutils/sarifutils.go b/formats/sarifutils/sarifutils.go index 493043d0..23a49ac8 100644 --- a/formats/sarifutils/sarifutils.go +++ b/formats/sarifutils/sarifutils.go @@ -59,6 +59,25 @@ func AggregateMultipleRunsIntoSingle(runs []*sarif.Run, destination *sarif.Run) } } +func GetResultProperty(key string, result *sarif.Result) string { + if result != nil && result.Properties != nil && result.Properties[key] != nil { + status, ok := result.Properties[key].(string) + if !ok { + return "" + } + return status + } + return "" +} + +func GetResultPropertyTokenValidation(result *sarif.Result) string { + return GetResultProperty("tokenValidation", result) +} + +func GetResultPropertyMetadata(result *sarif.Result) string { + return GetResultProperty("metadata", result) +} + func GetLocationRelatedCodeFlowsFromResult(location *sarif.Location, result *sarif.Result) (codeFlows []*sarif.CodeFlow) { for _, codeFlow := range result.CodeFlows { for _, stackTrace := range codeFlow.ThreadFlows { diff --git a/formats/sarifutils/test_sarifutils.go b/formats/sarifutils/test_sarifutils.go index 2de6c19e..457b3395 100644 --- a/formats/sarifutils/test_sarifutils.go +++ b/formats/sarifutils/test_sarifutils.go @@ -24,6 +24,20 @@ func CreateRunWithDummyResultAndRuleProperties(property, value string, result *s return run } +func CreateResultWithProperties(msg, ruleId, level string, properties map[string]string, locations ...*sarif.Location) *sarif.Result { + result := &sarif.Result{ + Message: *sarif.NewTextMessage(msg), + Level: &level, + RuleID: &ruleId, + Locations: locations, + } + result.Properties = map[string]interface{}{} + for key, val := range properties { + result.Properties[key] = val + } + return result +} + func CreateResultWithLocations(msg, ruleId, level string, locations ...*sarif.Location) *sarif.Result { return &sarif.Result{ Message: *sarif.NewTextMessage(msg), diff --git a/formats/simplejsonapi.go b/formats/simplejsonapi.go index 26ec121b..12994390 100644 --- a/formats/simplejsonapi.go +++ b/formats/simplejsonapi.go @@ -68,6 +68,8 @@ type SourceCodeRow struct { SeverityDetails Location Finding string `json:"finding,omitempty"` + TokenValidation string `json:"tokenValidation,omitempty"` + Metadata string `json:"metadata,omitempty"` ScannerDescription string `json:"scannerDescription,omitempty"` CodeFlow [][]Location `json:"codeFlow,omitempty"` } diff --git a/formats/table.go b/formats/table.go index fc9486d9..90521755 100644 --- a/formats/table.go +++ b/formats/table.go @@ -124,10 +124,12 @@ type cveTableRow struct { } type secretsTableRow struct { - severity string `col-name:"Severity"` - file string `col-name:"File"` - lineColumn string `col-name:"Line:Column"` - secret string `col-name:"Secret"` + severity string `col-name:"Severity"` + file string `col-name:"File"` + lineColumn string `col-name:"Line:Column"` + secret string `col-name:"Secret"` + tokenValidation string `col-name:"Token Validation" omitempty:"true"` + metadata string `col-name:"Metadata" omitempty:"true"` } type iacOrSastTableRow struct { diff --git a/go.mod b/go.mod index dfa53f0e..5eaee6e0 100644 --- a/go.mod +++ b/go.mod @@ -116,7 +116,7 @@ require ( // replace github.com/jfrog/jfrog-cli-core/v2 => github.com/jfrog/jfrog-cli-core/v2 dev -// replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go dev +replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go v1.28.1-0.20240813075119-1f32e208a317 //replace github.com/jfrog/build-info-go => github.com/jfrog/build-info-go dev diff --git a/go.sum b/go.sum index 9090ea91..e1741677 100644 --- a/go.sum +++ b/go.sum @@ -900,8 +900,8 @@ github.com/jfrog/jfrog-apps-config v1.0.1 h1:mtv6k7g8A8BVhlHGlSveapqf4mJfonwvXYL github.com/jfrog/jfrog-apps-config v1.0.1/go.mod h1:8AIIr1oY9JuH5dylz2S6f8Ym2MaadPLR6noCBO4C22w= github.com/jfrog/jfrog-cli-core/v2 v2.54.1 h1:oNIsqUVJ/P17qEcHgj9/c1nfO23stqqj1sHB7ldFNmQ= github.com/jfrog/jfrog-cli-core/v2 v2.54.1/go.mod h1:o8Ux0XiXWayxBXbtkMd5Vbs2YJZZDNiS9jtN6yQ4Ur8= -github.com/jfrog/jfrog-client-go v1.43.2 h1:NLSTTSFUkrNiSYs8rpRW7/sd6gDTPOi/eMVkGEarXq0= -github.com/jfrog/jfrog-client-go v1.43.2/go.mod h1:JUevXnjHbGL0MIIPs48L/axJMW/q4ioWMR1e1NuVn8w= +github.com/jfrog/jfrog-client-go v1.28.1-0.20240813075119-1f32e208a317 h1:X/yvoyo4EvjQwyvGkoZ2z1p8UCLy00WWl3uMN9X/cbk= +github.com/jfrog/jfrog-client-go v1.28.1-0.20240813075119-1f32e208a317/go.mod h1:JUevXnjHbGL0MIIPs48L/axJMW/q4ioWMR1e1NuVn8w= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= diff --git a/jas/analyzermanager.go b/jas/analyzermanager.go index dee11947..78cbbc29 100644 --- a/jas/analyzermanager.go +++ b/jas/analyzermanager.go @@ -42,6 +42,8 @@ const ( jfrogCliAnalyzerManagerVersionEnvVariable = "JFROG_CLI_ANALYZER_MANAGER_VERSION" JfPackageManagerEnvVariable = "AM_PACKAGE_MANAGER" JfLanguageEnvVariable = "AM_LANGUAGE" + // #nosec G101 -- Not credentials. + JfSecretValidationEnvVariable = "JF_VALIDATE_SECRETS" ) var exitCodeErrorsMap = map[int]string{ diff --git a/jas/common.go b/jas/common.go index a46e6db6..4150c37e 100644 --- a/jas/common.go +++ b/jas/common.go @@ -213,7 +213,7 @@ func InitJasTest(t *testing.T, workingDirs ...string) (*JasScanner, func()) { jfrogAppsConfigForTest, err := CreateJFrogAppsConfig(workingDirs) assert.NoError(t, err) scanner := &JasScanner{} - scanner, err = CreateJasScanner(scanner, jfrogAppsConfigForTest, &FakeServerDetails, GetAnalyzerManagerXscEnvVars("")) + scanner, err = CreateJasScanner(scanner, jfrogAppsConfigForTest, &FakeServerDetails, GetAnalyzerManagerXscEnvVars("", false)) assert.NoError(t, err) return scanner, func() { assert.NoError(t, scanner.ScannerDirCleanupFunc()) @@ -270,7 +270,25 @@ func convertToFilesExcludePatterns(excludePatterns []string) []string { return patterns } -func GetAnalyzerManagerXscEnvVars(msi string, technologies ...techutils.Technology) map[string]string { +func CheckForSecretValidation(xrayManager *xray.XrayServicesManager, xrayVersion string, validateSecrets bool) bool { + dynamicTokenVersionMismatchErr := goclientutils.ValidateMinimumVersion(goclientutils.Xray, xrayVersion, jasutils.DynamicTokenValidationMinXrayVersion) + if dynamicTokenVersionMismatchErr != nil { + if validateSecrets { + log.Warn("Token validation (--validate-secrets flag) is not supported in your xray version") + } + return false + } + // Ordered By importance + // first check for flag and second check for env var + if validateSecrets || strings.ToLower(os.Getenv("JF_VALIDATE_SECRETS")) == "true" { + return true + } + // third check for platform api + isEnabled, err := xrayManager.IsTokenValidationEnabled() + return err == nil && isEnabled +} + +func GetAnalyzerManagerXscEnvVars(msi string, validateSecrets bool, technologies ...techutils.Technology) map[string]string { envVars := map[string]string{utils.JfMsiEnvVariable: msi} if len(technologies) != 1 { return envVars @@ -278,6 +296,7 @@ func GetAnalyzerManagerXscEnvVars(msi string, technologies ...techutils.Technolo technology := technologies[0] envVars[JfPackageManagerEnvVariable] = technology.String() envVars[JfLanguageEnvVariable] = string(techutils.TechnologyToLanguage(technology)) + envVars[JfSecretValidationEnvVariable] = strconv.FormatBool(validateSecrets) return envVars } diff --git a/jas/common_test.go b/jas/common_test.go index 50ef1a44..14adf833 100644 --- a/jas/common_test.go +++ b/jas/common_test.go @@ -183,7 +183,7 @@ func TestGetAnalyzerManagerXscEnvVars(t *testing.T) { } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - assert.Equal(t, test.expectedOutput, GetAnalyzerManagerXscEnvVars(test.msi, test.technologies...)) + assert.Equal(t, test.expectedOutput, GetAnalyzerManagerXscEnvVars(test.msi, false, test.technologies...)) }) } } diff --git a/jas/runner/jasrunner_test.go b/jas/runner/jasrunner_test.go index 886b3e3b..eea3664c 100644 --- a/jas/runner/jasrunner_test.go +++ b/jas/runner/jasrunner_test.go @@ -27,7 +27,7 @@ func TestGetExtendedScanResults_AnalyzerManagerDoesntExist(t *testing.T) { assert.NoError(t, os.Unsetenv(coreutils.HomeDir)) }() scanner := &jas.JasScanner{} - _, err = jas.CreateJasScanner(scanner, nil, &jas.FakeServerDetails, jas.GetAnalyzerManagerXscEnvVars("")) + _, err = jas.CreateJasScanner(scanner, nil, &jas.FakeServerDetails, jas.GetAnalyzerManagerXscEnvVars("", false)) assert.Error(t, err) assert.ErrorContains(t, err, "unable to locate the analyzer manager package. Advanced security scans cannot be performed without this package") } @@ -37,7 +37,7 @@ func TestGetExtendedScanResults_ServerNotValid(t *testing.T) { scanResults := &utils.Results{ScaResults: []*utils.ScaScanResult{{Technology: techutils.Pip, XrayResults: jas.FakeBasicXrayResults}}, ExtendedScanResults: &utils.ExtendedScanResults{}} scanner := &jas.JasScanner{} - jasScanner, err := jas.CreateJasScanner(scanner, nil, &jas.FakeServerDetails, jas.GetAnalyzerManagerXscEnvVars("", scanResults.GetScaScannedTechnologies()...)) + jasScanner, err := jas.CreateJasScanner(scanner, nil, &jas.FakeServerDetails, jas.GetAnalyzerManagerXscEnvVars("", false, scanResults.GetScaScannedTechnologies()...)) assert.NoError(t, err) err = AddJasScannersTasks(securityParallelRunnerForTest, scanResults, &[]string{"issueId_1_direct_dependency", "issueId_2_direct_dependency"}, nil, false, jasScanner, applicability.ApplicabilityScannerType, secrets.SecretsScannerType, securityParallelRunnerForTest.AddErrorToChan, utils.GetAllSupportedScans()) assert.NoError(t, err) @@ -48,7 +48,7 @@ func TestGetExtendedScanResults_AnalyzerManagerReturnsError(t *testing.T) { jfrogAppsConfigForTest, _ := jas.CreateJFrogAppsConfig(nil) scanner := &jas.JasScanner{} - scanner, _ = jas.CreateJasScanner(scanner, nil, &jas.FakeServerDetails, jas.GetAnalyzerManagerXscEnvVars("")) + scanner, _ = jas.CreateJasScanner(scanner, nil, &jas.FakeServerDetails, jas.GetAnalyzerManagerXscEnvVars("", false)) _, err := applicability.RunApplicabilityScan(jas.FakeBasicXrayResults, []string{"issueId_2_direct_dependency", "issueId_1_direct_dependency"}, scanner, false, applicability.ApplicabilityScannerType, jfrogAppsConfigForTest.Modules[0], 0) diff --git a/utils/jasutils/jasutils.go b/utils/jasutils/jasutils.go index a9f83170..e4a9bb59 100644 --- a/utils/jasutils/jasutils.go +++ b/utils/jasutils/jasutils.go @@ -10,6 +10,10 @@ const ( ApplicabilityRuleIdPrefix = "applic_" ) +const ( + DynamicTokenValidationMinXrayVersion = "3.101.0" +) + const ( Applicability JasScanType = "Applicability" Secrets JasScanType = "Secrets" @@ -82,6 +86,14 @@ var applicableMapToScore = map[string]int{ "NotApplicable": 0, } +var TokenValidationOrder = map[string]int{ + "Active": 1, + "Inactive": 2, + "Unsupported": 3, + "Unavailable": 4, + "": 5, +} + func ConvertApplicableToScore(applicability string) int { if level, ok := applicableMapToScore[strings.ToLower(applicability)]; ok { return level diff --git a/utils/results.go b/utils/results.go index dd51c053..80bce241 100644 --- a/utils/results.go +++ b/utils/results.go @@ -142,6 +142,7 @@ type ExtendedScanResults struct { IacScanResults []*sarif.Run SastScanResults []*sarif.Run EntitledForJas bool + SecretValidation bool } func (e *ExtendedScanResults) IsIssuesFound() bool { diff --git a/utils/resultstable.go b/utils/resultstable.go index 1ad6daae..9ff256b9 100644 --- a/utils/resultstable.go +++ b/utils/resultstable.go @@ -344,6 +344,7 @@ func PrepareSecrets(secrets []*sarif.Run) []formats.SourceCodeRow { func prepareSecrets(secrets []*sarif.Run, isTable bool) []formats.SourceCodeRow { var secretsRows []formats.SourceCodeRow + tokenValidationActivated := false for _, secretRun := range secrets { for _, secretResult := range secretRun.Results { currSeverity, err := severityutils.ParseSeverity(sarifutils.GetResultLevel(secretResult), true) @@ -352,25 +353,31 @@ func prepareSecrets(secrets []*sarif.Run, isTable bool) []formats.SourceCodeRow currSeverity = severityutils.Unknown } for _, location := range secretResult.Locations { - secretsRows = append(secretsRows, - formats.SourceCodeRow{ - SeverityDetails: severityutils.GetAsDetails(currSeverity, jasutils.Applicable, isTable), - Finding: sarifutils.GetResultMsgText(secretResult), - Location: formats.Location{ - File: sarifutils.GetRelativeLocationFileName(location, secretRun.Invocations), - StartLine: sarifutils.GetLocationStartLine(location), - StartColumn: sarifutils.GetLocationStartColumn(location), - EndLine: sarifutils.GetLocationEndLine(location), - EndColumn: sarifutils.GetLocationEndColumn(location), - Snippet: sarifutils.GetLocationSnippet(location), - }, + secretsRows = append(secretsRows, formats.SourceCodeRow{ + SeverityDetails: severityutils.GetAsDetails(currSeverity, jasutils.Applicable, isTable), + Finding: sarifutils.GetResultMsgText(secretResult), + Location: formats.Location{ + File: sarifutils.GetRelativeLocationFileName(location, secretRun.Invocations), + StartLine: sarifutils.GetLocationStartLine(location), + StartColumn: sarifutils.GetLocationStartColumn(location), + EndLine: sarifutils.GetLocationEndLine(location), + EndColumn: sarifutils.GetLocationEndColumn(location), + Snippet: sarifutils.GetLocationSnippet(location), }, + TokenValidation: sarifutils.GetResultPropertyTokenValidation(secretResult), + Metadata: sarifutils.GetResultPropertyMetadata(secretResult), + }, ) } } } sort.Slice(secretsRows, func(i, j int) bool { + if tokenValidationActivated { + if jasutils.TokenValidationOrder[secretsRows[i].TokenValidation] != jasutils.TokenValidationOrder[secretsRows[j].TokenValidation] { + return jasutils.TokenValidationOrder[secretsRows[i].TokenValidation] < jasutils.TokenValidationOrder[secretsRows[j].TokenValidation] + } + } return secretsRows[i].SeverityNumValue > secretsRows[j].SeverityNumValue }) diff --git a/utils/resultstable_test.go b/utils/resultstable_test.go index ea41591c..fd8e6df0 100644 --- a/utils/resultstable_test.go +++ b/utils/resultstable_test.go @@ -1097,6 +1097,71 @@ func TestPrepareSecrets(t *testing.T) { }, }, }, + { + name: "Prepare Secret run - with results and tokens validation", + input: []*sarif.Run{ + sarifutils.CreateRunWithDummyResults(sarifutils.CreateResultWithLocations("secret finding", "rule2", "note", sarifutils.CreateLocation("file://wd/file", 1, 2, 3, 4, "some-secret-snippet"))), + sarifutils.CreateRunWithDummyResults( + sarifutils.CreateResultWithProperties("other secret finding", "rule2", "note", map[string]string{"tokenValidation": "Inactive", "metadata": ""}, sarifutils.CreateLocation("file://wd/file", 1, 2, 3, 4, "some-secret-snippet")), + ), + sarifutils.CreateRunWithDummyResults( + sarifutils.CreateResultWithProperties("another secret finding", "rule2", "note", map[string]string{"tokenValidation": "Active", "metadata": "testmetadata"}, sarifutils.CreateLocation("file://wd/file", 1, 2, 3, 4, "some-secret-snippet")), + ), + }, + expectedOutput: []formats.SourceCodeRow{ + { + SeverityDetails: formats.SeverityDetails{ + Severity: "Low", + SeverityNumValue: 11, + }, + TokenValidation: "", + Metadata: "", + Finding: "secret finding", + Location: formats.Location{ + File: "wd/file", + StartLine: 1, + StartColumn: 2, + EndLine: 3, + EndColumn: 4, + Snippet: "some-secret-snippet", + }, + }, + { + SeverityDetails: formats.SeverityDetails{ + Severity: "Low", + SeverityNumValue: 11, + }, + TokenValidation: "Inactive", + Metadata: "", + Finding: "other secret finding", + Location: formats.Location{ + File: "wd/file", + StartLine: 1, + StartColumn: 2, + EndLine: 3, + EndColumn: 4, + Snippet: "some-secret-snippet", + }, + }, + { + SeverityDetails: formats.SeverityDetails{ + Severity: "Low", + SeverityNumValue: 11, + }, + TokenValidation: "Active", + Metadata: "testmetadata", + Finding: "another secret finding", + Location: formats.Location{ + File: "wd/file", + StartLine: 1, + StartColumn: 2, + EndLine: 3, + EndColumn: 4, + Snippet: "some-secret-snippet", + }, + }, + }, + }, } for _, tc := range testCases { diff --git a/utils/utils.go b/utils/utils.go index bec647ca..bb75ab01 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -18,11 +18,12 @@ var ( ) const ( - ContextualAnalysisScan SubScanType = "contextual_analysis" - ScaScan SubScanType = "sca" - IacScan SubScanType = "iac" - SastScan SubScanType = "sast" - SecretsScan SubScanType = "secrets" + ContextualAnalysisScan SubScanType = "contextual_analysis" + ScaScan SubScanType = "sca" + IacScan SubScanType = "iac" + SastScan SubScanType = "sast" + SecretsScan SubScanType = "secrets" + SecretTokenValidationScan SubScanType = "secrets_token_validation" ) type SubScanType string @@ -32,7 +33,7 @@ func (s SubScanType) String() string { } func GetAllSupportedScans() []SubScanType { - return []SubScanType{ScaScan, ContextualAnalysisScan, IacScan, SastScan, SecretsScan} + return []SubScanType{ScaScan, ContextualAnalysisScan, IacScan, SastScan, SecretsScan, SecretTokenValidationScan} } // map[string]string to []string (key=value format) From 432173818e6394706bb077ecd96f44c998914856 Mon Sep 17 00:00:00 2001 From: barv Date: Tue, 13 Aug 2024 19:19:56 +0300 Subject: [PATCH 02/32] Tests + fixes --- audit_test.go | 16 +++++++++++++++- jas/common.go | 2 +- .../projects/jas/jas/secrets/api_secrets/tokens | 6 ++++++ tests/utils/test_validation.go | 14 ++++++++++++++ utils/jasutils/jasutils.go | 1 + utils/resultstable.go | 7 ++----- 6 files changed, 39 insertions(+), 7 deletions(-) create mode 100644 tests/testdata/projects/jas/jas/secrets/api_secrets/tokens diff --git a/audit_test.go b/audit_test.go index 4987e691..12419fb8 100644 --- a/audit_test.go +++ b/audit_test.go @@ -3,6 +3,7 @@ package main import ( "encoding/json" "fmt" + "github.com/jfrog/jfrog-cli-security/utils/jasutils" "os" "os/exec" "path/filepath" @@ -474,6 +475,11 @@ func TestXrayAuditJasSimpleJson(t *testing.T) { securityTestUtils.VerifySimpleJsonJasResults(t, output, 1, 9, 6, 3, 0, 2, 2) } +func TestXrayAuditJasSimpleJsonWithTokenValidation(t *testing.T) { + output := testXrayAuditJasWithTokenValidation(t, securityTests.PlatformCli, filepath.Join("jas", "jas"), "3") + securityTestUtils.VerifySimpleJsonScanTokenValidationResults(t, output, 5) +} + func TestXrayAuditJasSimpleJsonWithOneThread(t *testing.T) { output := testXrayAuditJas(t, securityTests.PlatformCli, filepath.Join("jas", "jas"), "1") securityTestUtils.VerifySimpleJsonScanResults(t, output, 0, 8, 0) @@ -491,7 +497,7 @@ func TestXrayAuditJasNoViolationsSimpleJson(t *testing.T) { securityTestUtils.VerifySimpleJsonJasResults(t, output, 0, 0, 0, 0, 0, 0, 1) } -func testXrayAuditJas(t *testing.T, testCli *coreTests.JfrogCli, project string, threads string) string { +func testXrayAuditJas(t *testing.T, testCli *coreTests.JfrogCli, project string, threads string, validateSecrets ...bool) string { securityTestUtils.InitSecurityTest(t, scangraph.GraphScanMinXrayVersion) tempDirPath, createTempDirCallback := coreTests.CreateTempDirWithCallbackAndAssert(t) defer createTempDirCallback() @@ -505,9 +511,17 @@ func testXrayAuditJas(t *testing.T, testCli *coreTests.JfrogCli, project string, assert.NoError(t, err) chdirCallback := clientTests.ChangeDirWithCallback(t, baseWd, tempDirPath) defer chdirCallback() + if validateSecrets[0] { + return testCli.WithoutCredentials().RunCliCmdWithOutput(t, "audit", "--validate-secrets", "--secrets", "--format="+string(format.SimpleJson), "--threads="+threads) + } return testCli.WithoutCredentials().RunCliCmdWithOutput(t, "audit", "--format="+string(format.SimpleJson), "--threads="+threads) } +func testXrayAuditJasWithTokenValidation(t *testing.T, testCli *coreTests.JfrogCli, project string, threads string) string { + securityTestUtils.InitSecurityTest(t, jasutils.DynamicTokenValidationMinXrayVersion) + return testXrayAuditJas(t, testCli, project, threads, true) +} + func TestXrayAuditDetectTech(t *testing.T) { securityTestUtils.InitSecurityTest(t, scangraph.GraphScanMinXrayVersion) tempDirPath, createTempDirCallback := coreTests.CreateTempDirWithCallbackAndAssert(t) diff --git a/jas/common.go b/jas/common.go index 4150c37e..845f135f 100644 --- a/jas/common.go +++ b/jas/common.go @@ -290,13 +290,13 @@ func CheckForSecretValidation(xrayManager *xray.XrayServicesManager, xrayVersion func GetAnalyzerManagerXscEnvVars(msi string, validateSecrets bool, technologies ...techutils.Technology) map[string]string { envVars := map[string]string{utils.JfMsiEnvVariable: msi} + envVars[JfSecretValidationEnvVariable] = strconv.FormatBool(validateSecrets) if len(technologies) != 1 { return envVars } technology := technologies[0] envVars[JfPackageManagerEnvVariable] = technology.String() envVars[JfLanguageEnvVariable] = string(techutils.TechnologyToLanguage(technology)) - envVars[JfSecretValidationEnvVariable] = strconv.FormatBool(validateSecrets) return envVars } diff --git a/tests/testdata/projects/jas/jas/secrets/api_secrets/tokens b/tests/testdata/projects/jas/jas/secrets/api_secrets/tokens new file mode 100644 index 00000000..feb5fe73 --- /dev/null +++ b/tests/testdata/projects/jas/jas/secrets/api_secrets/tokens @@ -0,0 +1,6 @@ +API_KEY=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 +API_KEY_TWO=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 +API_KEY_THREE=ghp_SerULubAEgmUvNss9EJMJLVYZ2Iprm29Mdlg +API_KEY_FOUR=sl.BxYhe_DcMZdu0TiwIqjSxxWOG02QQ2aPk17N94bsnyPCNoZ1IbD5as-LUOFRF-t7qKJaoUUz_XpFxs1WFe9nZZXMkUxcXuyoV6Caje3E8Lyx55w0oTEo29Fpolfg8d_QEBIvqpJUiB9C +API_KEY_FIVE=sl.BxPWLN25rQ2VVsFIy0AvjHY-Tiy1Pjuu9VZ-62fobHruF_5ANABMm48aG4Tjx6YohNF7mZia2zZVLbvqTlklsAQe41zzz0lqOp1dyCf-FFY-GFC9gHZ-gECgytQL8WW26j77W3jcS4ee +API_KEY_SIX=glpat-QXnCVeWcFaUMRZM9sAUZ \ No newline at end of file diff --git a/tests/utils/test_validation.go b/tests/utils/test_validation.go index ece7b2c2..62f65a1e 100644 --- a/tests/utils/test_validation.go +++ b/tests/utils/test_validation.go @@ -65,6 +65,20 @@ func VerifySimpleJsonScanResults(t *testing.T, content string, minViolations, mi } } +func VerifySimpleJsonScanTokenValidationResults(t *testing.T, content string, minInactives int) { + var results formats.SimpleJsonResults + err := json.Unmarshal([]byte(content), &results) + if assert.NoError(t, err) { + count_inactives := 0 + for _, result := range results.Secrets { + if result.TokenValidation == "Inactive" { + count_inactives += 1 + } + } + assert.GreaterOrEqual(t, count_inactives, minInactives) + } +} + func VerifySimpleJsonJasResults(t *testing.T, content string, minSastViolations, minIacViolations, minSecrets, minApplicable, minUndetermined, minNotCovered, minNotApplicable int) { var results formats.SimpleJsonResults diff --git a/utils/jasutils/jasutils.go b/utils/jasutils/jasutils.go index e4a9bb59..d8c9e888 100644 --- a/utils/jasutils/jasutils.go +++ b/utils/jasutils/jasutils.go @@ -92,6 +92,7 @@ var TokenValidationOrder = map[string]int{ "Unsupported": 3, "Unavailable": 4, "": 5, + "N/A": 6, } func ConvertApplicableToScore(applicability string) int { diff --git a/utils/resultstable.go b/utils/resultstable.go index 9ff256b9..dfc0d69c 100644 --- a/utils/resultstable.go +++ b/utils/resultstable.go @@ -344,7 +344,6 @@ func PrepareSecrets(secrets []*sarif.Run) []formats.SourceCodeRow { func prepareSecrets(secrets []*sarif.Run, isTable bool) []formats.SourceCodeRow { var secretsRows []formats.SourceCodeRow - tokenValidationActivated := false for _, secretRun := range secrets { for _, secretResult := range secretRun.Results { currSeverity, err := severityutils.ParseSeverity(sarifutils.GetResultLevel(secretResult), true) @@ -373,10 +372,8 @@ func prepareSecrets(secrets []*sarif.Run, isTable bool) []formats.SourceCodeRow } sort.Slice(secretsRows, func(i, j int) bool { - if tokenValidationActivated { - if jasutils.TokenValidationOrder[secretsRows[i].TokenValidation] != jasutils.TokenValidationOrder[secretsRows[j].TokenValidation] { - return jasutils.TokenValidationOrder[secretsRows[i].TokenValidation] < jasutils.TokenValidationOrder[secretsRows[j].TokenValidation] - } + if jasutils.TokenValidationOrder[secretsRows[i].TokenValidation] != jasutils.TokenValidationOrder[secretsRows[j].TokenValidation] { + return jasutils.TokenValidationOrder[secretsRows[i].TokenValidation] < jasutils.TokenValidationOrder[secretsRows[j].TokenValidation] } return secretsRows[i].SeverityNumValue > secretsRows[j].SeverityNumValue }) From 62e70127fe080f582d8c2c95e29f037951f70e19 Mon Sep 17 00:00:00 2001 From: barv Date: Wed, 14 Aug 2024 17:55:03 +0300 Subject: [PATCH 03/32] Tests + fixes --- formats/conversion.go | 27 ++++++++++++++++++--------- utils/resultstable.go | 25 +++++++++++++++---------- utils/resultstable_test.go | 3 ++- 3 files changed, 35 insertions(+), 20 deletions(-) diff --git a/formats/conversion.go b/formats/conversion.go index 95c33268..7012d91c 100644 --- a/formats/conversion.go +++ b/formats/conversion.go @@ -141,16 +141,25 @@ func ConvertToOperationalRiskViolationScanTableRow(rows []OperationalRiskViolati return } -func ConvertToSecretsTableRow(rows []SourceCodeRow) (tableRows []secretsTableRow) { +func ConvertToSecretsTableRow(rows []SourceCodeRow, tokenValidation bool) (tableRows []secretsTableRow) { for i := range rows { - tableRows = append(tableRows, secretsTableRow{ - severity: rows[i].Severity, - file: rows[i].File, - lineColumn: strconv.Itoa(rows[i].StartLine) + ":" + strconv.Itoa(rows[i].StartColumn), - secret: rows[i].Snippet, - tokenValidation: rows[i].TokenValidation, - metadata: rows[i].Metadata, - }) + newRow := secretsTableRow{ + severity: rows[i].Severity, + file: rows[i].File, + lineColumn: strconv.Itoa(rows[i].StartLine) + ":" + strconv.Itoa(rows[i].StartColumn), + secret: rows[i].Snippet, + } + if tokenValidation { + newRow.tokenValidation = "N/A" + newRow.metadata = "N/A" + if rows[i].TokenValidation != "" { + newRow.tokenValidation = rows[i].TokenValidation + } + if rows[i].Metadata != "" { + newRow.metadata = rows[i].Metadata + } + } + tableRows = append(tableRows, newRow) } return } diff --git a/utils/resultstable.go b/utils/resultstable.go index dfc0d69c..9e43a425 100644 --- a/utils/resultstable.go +++ b/utils/resultstable.go @@ -339,11 +339,13 @@ func PrepareLicenses(licenses []services.License) ([]formats.LicenseRow, error) // Prepare secrets for all non-table formats (without style or emoji) func PrepareSecrets(secrets []*sarif.Run) []formats.SourceCodeRow { - return prepareSecrets(secrets, false) + preparedSecrets, _ := prepareSecrets(secrets, false) + return preparedSecrets } -func prepareSecrets(secrets []*sarif.Run, isTable bool) []formats.SourceCodeRow { +func prepareSecrets(secrets []*sarif.Run, isTable bool) ([]formats.SourceCodeRow, bool) { var secretsRows []formats.SourceCodeRow + tokenValidationActivated := false for _, secretRun := range secrets { for _, secretResult := range secretRun.Results { currSeverity, err := severityutils.ParseSeverity(sarifutils.GetResultLevel(secretResult), true) @@ -352,7 +354,7 @@ func prepareSecrets(secrets []*sarif.Run, isTable bool) []formats.SourceCodeRow currSeverity = severityutils.Unknown } for _, location := range secretResult.Locations { - secretsRows = append(secretsRows, formats.SourceCodeRow{ + newRow := formats.SourceCodeRow{ SeverityDetails: severityutils.GetAsDetails(currSeverity, jasutils.Applicable, isTable), Finding: sarifutils.GetResultMsgText(secretResult), Location: formats.Location{ @@ -363,10 +365,13 @@ func prepareSecrets(secrets []*sarif.Run, isTable bool) []formats.SourceCodeRow EndColumn: sarifutils.GetLocationEndColumn(location), Snippet: sarifutils.GetLocationSnippet(location), }, - TokenValidation: sarifutils.GetResultPropertyTokenValidation(secretResult), - Metadata: sarifutils.GetResultPropertyMetadata(secretResult), - }, - ) + } + if tokenValidation := sarifutils.GetResultPropertyTokenValidation(secretResult); tokenValidation != "" { + newRow.TokenValidation = sarifutils.GetResultPropertyTokenValidation(secretResult) + newRow.Metadata = sarifutils.GetResultPropertyMetadata(secretResult) + tokenValidationActivated = true + } + secretsRows = append(secretsRows, newRow) } } } @@ -378,14 +383,14 @@ func prepareSecrets(secrets []*sarif.Run, isTable bool) []formats.SourceCodeRow return secretsRows[i].SeverityNumValue > secretsRows[j].SeverityNumValue }) - return secretsRows + return secretsRows, tokenValidationActivated } func PrintSecretsTable(secrets []*sarif.Run, entitledForSecretsScan bool) error { if entitledForSecretsScan { - secretsRows := prepareSecrets(secrets, true) + secretsRows, tokenValidationActivated := prepareSecrets(secrets, true) log.Output() - return coreutils.PrintTable(formats.ConvertToSecretsTableRow(secretsRows), "Secret Detection", + return coreutils.PrintTable(formats.ConvertToSecretsTableRow(secretsRows, tokenValidationActivated), "Secret Detection", "✨ No secrets were found ✨", false) } return nil diff --git a/utils/resultstable_test.go b/utils/resultstable_test.go index fd8e6df0..09a82e07 100644 --- a/utils/resultstable_test.go +++ b/utils/resultstable_test.go @@ -1166,7 +1166,8 @@ func TestPrepareSecrets(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - assert.ElementsMatch(t, tc.expectedOutput, prepareSecrets(tc.input, false)) + rows, _ := prepareSecrets(tc.input, false) + assert.ElementsMatch(t, tc.expectedOutput, rows) }) } } From bc6fa3daf1f1f61ac81689297e4a9466140e26da Mon Sep 17 00:00:00 2001 From: barv Date: Thu, 15 Aug 2024 10:42:48 +0300 Subject: [PATCH 04/32] Tests + fixes --- .../projects/jas/jas/secrets/api_secrets/tokens | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/testdata/projects/jas/jas/secrets/api_secrets/tokens b/tests/testdata/projects/jas/jas/secrets/api_secrets/tokens index feb5fe73..d68dd69d 100644 --- a/tests/testdata/projects/jas/jas/secrets/api_secrets/tokens +++ b/tests/testdata/projects/jas/jas/secrets/api_secrets/tokens @@ -1,6 +1,6 @@ -API_KEY=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 -API_KEY_TWO=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 -API_KEY_THREE=ghp_SerULubAEgmUvNss9EJMJLVYZ2Iprm29Mdlg -API_KEY_FOUR=sl.BxYhe_DcMZdu0TiwIqjSxxWOG02QQ2aPk17N94bsnyPCNoZ1IbD5as-LUOFRF-t7qKJaoUUz_XpFxs1WFe9nZZXMkUxcXuyoV6Caje3E8Lyx55w0oTEo29Fpolfg8d_QEBIvqpJUiB9C -API_KEY_FIVE=sl.BxPWLN25rQ2VVsFIy0AvjHY-Tiy1Pjuu9VZ-62fobHruF_5ANABMm48aG4Tjx6YohNF7mZia2zZVLbvqTlklsAQe41zzz0lqOp1dyCf-FFY-GFC9gHZ-gECgytQL8WW26j77W3jcS4ee -API_KEY_SIX=glpat-QXnCVeWcFaUMRZM9sAUZ \ No newline at end of file +API_KEY_ONE=gho_Xqx6UWZmFguhjQ3z7vCAeI4wzi6Duq32e0dl +API_KEY_TWO=ghp_SdrUHubAZgmUvNee9EJMJLVYZ4Qprm29PdM +API_KEY_THREE=ghp_RerJLubIEgmUvNss8YJMJLZ2Iprn29Mdlg +API_KEY_FOUR=sl.BxYle_DCNMFdu0KivrISxxWOG12QQ2aPk17N24bsjPCNoZ1IbD5as-LFOFRF-t7qKJzoUUz_XpExs1UFe9nZZXMvUxcXuyoV6Ccje4E8Ylx35w0oTEo21Fpolcg8d_QEBIvqvJUiB9C +API_KEY_FIVE=sl.BxPWLN3300VVsFIy1AvjHY-TYy2Pjuu8VZ-72fobJruF_5ANABMm38aG4Tjx5YohNF7mZia23ZVLBrqxlklsMQve1zzz0lqOp1yyCf-FWY-GFC9gH2-gECgyYQL9WW27j27W3jcS4ef +API_KEY_SIX=glpat-KXzCVeWcFaUMRZM9sBUZ \ No newline at end of file From 616b4c239c5da9d3c257f4e000f1fada06417759 Mon Sep 17 00:00:00 2001 From: barv Date: Thu, 15 Aug 2024 11:12:17 +0300 Subject: [PATCH 05/32] Tests + fixes --- go.mod | 22 +++++++++---------- go.sum | 11 ++++++++++ .../jas/jas/secrets/api_secrets/tokens | 12 +++++----- 3 files changed, 28 insertions(+), 17 deletions(-) diff --git a/go.mod b/go.mod index 5eaee6e0..9afb6234 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/beevik/etree v1.4.0 github.com/google/go-github/v56 v56.0.0 github.com/gookit/color v1.5.4 - github.com/jfrog/build-info-go v1.9.32 + github.com/jfrog/build-info-go v1.9.33 github.com/jfrog/froggit-go v1.16.1 github.com/jfrog/gofrog v1.7.5 github.com/jfrog/jfrog-apps-config v1.0.1 @@ -15,9 +15,9 @@ require ( github.com/magiconair/properties v1.8.7 github.com/owenrumney/go-sarif/v2 v2.3.0 github.com/stretchr/testify v1.9.0 - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 - golang.org/x/sync v0.7.0 - golang.org/x/text v0.16.0 + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa + golang.org/x/sync v0.8.0 + golang.org/x/text v0.17.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -100,14 +100,14 @@ require ( github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.9.0 // indirect - golang.org/x/crypto v0.25.0 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect + golang.org/x/crypto v0.26.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect golang.org/x/oauth2 v0.18.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/term v0.22.0 // indirect + golang.org/x/sys v0.23.0 // indirect + golang.org/x/term v0.23.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/tools v0.24.0 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/protobuf v1.33.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect @@ -116,7 +116,7 @@ require ( // replace github.com/jfrog/jfrog-cli-core/v2 => github.com/jfrog/jfrog-cli-core/v2 dev -replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go v1.28.1-0.20240813075119-1f32e208a317 +replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go v1.28.1-0.20240814160234-e68b65d94038 //replace github.com/jfrog/build-info-go => github.com/jfrog/build-info-go dev diff --git a/go.sum b/go.sum index e1741677..2a90ca4d 100644 --- a/go.sum +++ b/go.sum @@ -892,6 +892,7 @@ github.com/jfrog/archiver/v3 v3.6.1 h1:LOxnkw9pOn45DzCbZNFV6K0+6dCsQ0L8mR3ZcujO5 github.com/jfrog/archiver/v3 v3.6.1/go.mod h1:VgR+3WZS4N+i9FaDwLZbq+jeU4B4zctXL+gL4EMzfLw= github.com/jfrog/build-info-go v1.9.32 h1:PKXAMe84sMdob6eBtwwGz47Fz2cmjMwMPoHW8xuk08Q= github.com/jfrog/build-info-go v1.9.32/go.mod h1:JTGnENexG1jRhKWCkQtZuDb0PerlzlSzF5OmMLG9kfc= +github.com/jfrog/build-info-go v1.9.33/go.mod h1:JTGnENexG1jRhKWCkQtZuDb0PerlzlSzF5OmMLG9kfc= github.com/jfrog/froggit-go v1.16.1 h1:FBIM1qevX/ag9unfmpGzfmZ36D8ulOJ+DPTSFUk3l5U= github.com/jfrog/froggit-go v1.16.1/go.mod h1:TEJSzgiV+3D/GVGE8Y6j46ut1jrBLD1FL6WdMdKwwCE= github.com/jfrog/gofrog v1.7.5 h1:dFgtEDefJdlq9cqTRoe09RLxS5Bxbe1Ev5+E6SmZHcg= @@ -902,6 +903,7 @@ github.com/jfrog/jfrog-cli-core/v2 v2.54.1 h1:oNIsqUVJ/P17qEcHgj9/c1nfO23stqqj1s github.com/jfrog/jfrog-cli-core/v2 v2.54.1/go.mod h1:o8Ux0XiXWayxBXbtkMd5Vbs2YJZZDNiS9jtN6yQ4Ur8= github.com/jfrog/jfrog-client-go v1.28.1-0.20240813075119-1f32e208a317 h1:X/yvoyo4EvjQwyvGkoZ2z1p8UCLy00WWl3uMN9X/cbk= github.com/jfrog/jfrog-client-go v1.28.1-0.20240813075119-1f32e208a317/go.mod h1:JUevXnjHbGL0MIIPs48L/axJMW/q4ioWMR1e1NuVn8w= +github.com/jfrog/jfrog-client-go v1.28.1-0.20240814160234-e68b65d94038/go.mod h1:cRCuMvRgWJ6fSdyYs1pknBin41LLcXY94UOl7KHiQ8U= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= @@ -1125,6 +1127,7 @@ golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0 golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1142,6 +1145,7 @@ golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMk golang.org/x/exp v0.0.0-20220827204233-334a2380cb91/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= @@ -1186,6 +1190,7 @@ golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1249,6 +1254,7 @@ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1301,6 +1307,7 @@ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1394,6 +1401,7 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1407,6 +1415,7 @@ golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= +golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1426,6 +1435,7 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1497,6 +1507,7 @@ golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/tests/testdata/projects/jas/jas/secrets/api_secrets/tokens b/tests/testdata/projects/jas/jas/secrets/api_secrets/tokens index d68dd69d..feb5fe73 100644 --- a/tests/testdata/projects/jas/jas/secrets/api_secrets/tokens +++ b/tests/testdata/projects/jas/jas/secrets/api_secrets/tokens @@ -1,6 +1,6 @@ -API_KEY_ONE=gho_Xqx6UWZmFguhjQ3z7vCAeI4wzi6Duq32e0dl -API_KEY_TWO=ghp_SdrUHubAZgmUvNee9EJMJLVYZ4Qprm29PdM -API_KEY_THREE=ghp_RerJLubIEgmUvNss8YJMJLZ2Iprn29Mdlg -API_KEY_FOUR=sl.BxYle_DCNMFdu0KivrISxxWOG12QQ2aPk17N24bsjPCNoZ1IbD5as-LFOFRF-t7qKJzoUUz_XpExs1UFe9nZZXMvUxcXuyoV6Ccje4E8Ylx35w0oTEo21Fpolcg8d_QEBIvqvJUiB9C -API_KEY_FIVE=sl.BxPWLN3300VVsFIy1AvjHY-TYy2Pjuu8VZ-72fobJruF_5ANABMm38aG4Tjx5YohNF7mZia23ZVLBrqxlklsMQve1zzz0lqOp1yyCf-FWY-GFC9gH2-gECgyYQL9WW27j27W3jcS4ef -API_KEY_SIX=glpat-KXzCVeWcFaUMRZM9sBUZ \ No newline at end of file +API_KEY=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 +API_KEY_TWO=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 +API_KEY_THREE=ghp_SerULubAEgmUvNss9EJMJLVYZ2Iprm29Mdlg +API_KEY_FOUR=sl.BxYhe_DcMZdu0TiwIqjSxxWOG02QQ2aPk17N94bsnyPCNoZ1IbD5as-LUOFRF-t7qKJaoUUz_XpFxs1WFe9nZZXMkUxcXuyoV6Caje3E8Lyx55w0oTEo29Fpolfg8d_QEBIvqpJUiB9C +API_KEY_FIVE=sl.BxPWLN25rQ2VVsFIy0AvjHY-Tiy1Pjuu9VZ-62fobHruF_5ANABMm48aG4Tjx6YohNF7mZia2zZVLbvqTlklsAQe41zzz0lqOp1dyCf-FFY-GFC9gHZ-gECgytQL8WW26j77W3jcS4ee +API_KEY_SIX=glpat-QXnCVeWcFaUMRZM9sAUZ \ No newline at end of file From b9474b50b75bb01465ba7ee6898f8d8af1a1c501 Mon Sep 17 00:00:00 2001 From: barv Date: Thu, 15 Aug 2024 11:22:31 +0300 Subject: [PATCH 06/32] Tests + fixes --- go.mod | 2 +- go.sum | 35 ++++++++++++----------------------- 2 files changed, 13 insertions(+), 24 deletions(-) diff --git a/go.mod b/go.mod index 9afb6234..137e340f 100644 --- a/go.mod +++ b/go.mod @@ -116,7 +116,7 @@ require ( // replace github.com/jfrog/jfrog-cli-core/v2 => github.com/jfrog/jfrog-cli-core/v2 dev -replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go v1.28.1-0.20240814160234-e68b65d94038 +//replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go v1.28.1-0.20240814160234-e68b65d94038 //replace github.com/jfrog/build-info-go => github.com/jfrog/build-info-go dev diff --git a/go.sum b/go.sum index 2a90ca4d..75d31ab3 100644 --- a/go.sum +++ b/go.sum @@ -890,8 +890,7 @@ github.com/jedib0t/go-pretty/v6 v6.5.9 h1:ACteMBRrrmm1gMsXe9PSTOClQ63IXDUt03H5U+ github.com/jedib0t/go-pretty/v6 v6.5.9/go.mod h1:zbn98qrYlh95FIhwwsbIip0LYpwSG8SUOScs+v9/t0E= github.com/jfrog/archiver/v3 v3.6.1 h1:LOxnkw9pOn45DzCbZNFV6K0+6dCsQ0L8mR3ZcujO5eI= github.com/jfrog/archiver/v3 v3.6.1/go.mod h1:VgR+3WZS4N+i9FaDwLZbq+jeU4B4zctXL+gL4EMzfLw= -github.com/jfrog/build-info-go v1.9.32 h1:PKXAMe84sMdob6eBtwwGz47Fz2cmjMwMPoHW8xuk08Q= -github.com/jfrog/build-info-go v1.9.32/go.mod h1:JTGnENexG1jRhKWCkQtZuDb0PerlzlSzF5OmMLG9kfc= +github.com/jfrog/build-info-go v1.9.33 h1:TEeTHDc3tEwZe/7kKhm1hQDd5vA/HnVhp1ZczUOWExk= github.com/jfrog/build-info-go v1.9.33/go.mod h1:JTGnENexG1jRhKWCkQtZuDb0PerlzlSzF5OmMLG9kfc= github.com/jfrog/froggit-go v1.16.1 h1:FBIM1qevX/ag9unfmpGzfmZ36D8ulOJ+DPTSFUk3l5U= github.com/jfrog/froggit-go v1.16.1/go.mod h1:TEJSzgiV+3D/GVGE8Y6j46ut1jrBLD1FL6WdMdKwwCE= @@ -901,9 +900,8 @@ github.com/jfrog/jfrog-apps-config v1.0.1 h1:mtv6k7g8A8BVhlHGlSveapqf4mJfonwvXYL github.com/jfrog/jfrog-apps-config v1.0.1/go.mod h1:8AIIr1oY9JuH5dylz2S6f8Ym2MaadPLR6noCBO4C22w= github.com/jfrog/jfrog-cli-core/v2 v2.54.1 h1:oNIsqUVJ/P17qEcHgj9/c1nfO23stqqj1sHB7ldFNmQ= github.com/jfrog/jfrog-cli-core/v2 v2.54.1/go.mod h1:o8Ux0XiXWayxBXbtkMd5Vbs2YJZZDNiS9jtN6yQ4Ur8= -github.com/jfrog/jfrog-client-go v1.28.1-0.20240813075119-1f32e208a317 h1:X/yvoyo4EvjQwyvGkoZ2z1p8UCLy00WWl3uMN9X/cbk= -github.com/jfrog/jfrog-client-go v1.28.1-0.20240813075119-1f32e208a317/go.mod h1:JUevXnjHbGL0MIIPs48L/axJMW/q4ioWMR1e1NuVn8w= -github.com/jfrog/jfrog-client-go v1.28.1-0.20240814160234-e68b65d94038/go.mod h1:cRCuMvRgWJ6fSdyYs1pknBin41LLcXY94UOl7KHiQ8U= +github.com/jfrog/jfrog-client-go v1.43.2 h1:NLSTTSFUkrNiSYs8rpRW7/sd6gDTPOi/eMVkGEarXq0= +github.com/jfrog/jfrog-client-go v1.43.2/go.mod h1:JUevXnjHbGL0MIIPs48L/axJMW/q4ioWMR1e1NuVn8w= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= @@ -1125,8 +1123,7 @@ golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2Uz golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1143,8 +1140,7 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20220827204233-334a2380cb91/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= @@ -1188,8 +1184,7 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91 golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1252,8 +1247,7 @@ golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1305,8 +1299,7 @@ golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1399,8 +1392,7 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1413,8 +1405,7 @@ golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= -golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= -golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= +golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1433,8 +1424,7 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1505,8 +1495,7 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 276f7e30f234edd669fc2848b8da106c5c9fd58c Mon Sep 17 00:00:00 2001 From: barv Date: Thu, 15 Aug 2024 11:38:30 +0300 Subject: [PATCH 07/32] Tests + fixes --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 137e340f..9afb6234 100644 --- a/go.mod +++ b/go.mod @@ -116,7 +116,7 @@ require ( // replace github.com/jfrog/jfrog-cli-core/v2 => github.com/jfrog/jfrog-cli-core/v2 dev -//replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go v1.28.1-0.20240814160234-e68b65d94038 +replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go v1.28.1-0.20240814160234-e68b65d94038 //replace github.com/jfrog/build-info-go => github.com/jfrog/build-info-go dev diff --git a/go.sum b/go.sum index 75d31ab3..5b11909b 100644 --- a/go.sum +++ b/go.sum @@ -900,8 +900,8 @@ github.com/jfrog/jfrog-apps-config v1.0.1 h1:mtv6k7g8A8BVhlHGlSveapqf4mJfonwvXYL github.com/jfrog/jfrog-apps-config v1.0.1/go.mod h1:8AIIr1oY9JuH5dylz2S6f8Ym2MaadPLR6noCBO4C22w= github.com/jfrog/jfrog-cli-core/v2 v2.54.1 h1:oNIsqUVJ/P17qEcHgj9/c1nfO23stqqj1sHB7ldFNmQ= github.com/jfrog/jfrog-cli-core/v2 v2.54.1/go.mod h1:o8Ux0XiXWayxBXbtkMd5Vbs2YJZZDNiS9jtN6yQ4Ur8= -github.com/jfrog/jfrog-client-go v1.43.2 h1:NLSTTSFUkrNiSYs8rpRW7/sd6gDTPOi/eMVkGEarXq0= -github.com/jfrog/jfrog-client-go v1.43.2/go.mod h1:JUevXnjHbGL0MIIPs48L/axJMW/q4ioWMR1e1NuVn8w= +github.com/jfrog/jfrog-client-go v1.28.1-0.20240814160234-e68b65d94038 h1:gnltCt+/UMVI/S5Bwka5zw5VLSJlWLm309qkXd0UPos= +github.com/jfrog/jfrog-client-go v1.28.1-0.20240814160234-e68b65d94038/go.mod h1:cRCuMvRgWJ6fSdyYs1pknBin41LLcXY94UOl7KHiQ8U= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= From e60cadd02c7566dc861573c0c98bf567b717f4a3 Mon Sep 17 00:00:00 2001 From: barv Date: Thu, 15 Aug 2024 14:06:40 +0300 Subject: [PATCH 08/32] Tests + fixes --- scans_test.go | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/scans_test.go b/scans_test.go index ba6271d6..015b0e00 100644 --- a/scans_test.go +++ b/scans_test.go @@ -127,6 +127,11 @@ func TestDockerScan(t *testing.T) { // Image with 0 vulnerabilities runDockerScan(t, testCli, "busybox:1.35", "", 0, 0, 0) + + securityTestUtils.InitSecurityTest(t, jasutils.DynamicTokenValidationMinXrayVersion) + // image with inactive tokens + tokensImageToScan := "inactiveTokens:latest" + runDockerScanWithTokenValidation(t, testCli, tokensImageToScan, 5) } func initNativeDockerWithXrayTest(t *testing.T) (mockCli *coreTests.JfrogCli, cleanUp func()) { @@ -161,6 +166,22 @@ func runDockerScan(t *testing.T, testCli *coreTests.JfrogCli, imageName, watchNa } } +func runDockerScanWithTokenValidation(t *testing.T, testCli *coreTests.JfrogCli, imageName string, minInactives int) { + // Pull image from docker repo + imageTag := path.Join(*securityTests.ContainerRegistry, securityTests.DockerVirtualRepo, imageName) + dockerPullCommand := container.NewPullCommand(containerUtils.DockerClient) + dockerPullCommand.SetCmdParams([]string{"pull", imageTag}).SetImageTag(imageTag).SetRepo(securityTests.DockerVirtualRepo).SetServerDetails(securityTests.XrDetails).SetBuildConfiguration(new(build.BuildConfiguration)) + if assert.NoError(t, dockerPullCommand.Run()) { + defer commonTests.DeleteTestImage(t, imageTag, containerUtils.DockerClient) + // Run docker scan on image + cmdArgs := []string{"docker", "scan", "--validate-secrets", imageTag, "--server-id=default", "--licenses", "--format=json", "--fail=false", "--min-severity=low", "--fixable-only"} + output := testCli.WithoutCredentials().RunCliCmdWithOutput(t, cmdArgs...) + if assert.NotEmpty(t, output) { + securityTestUtils.VerifySimpleJsonScanTokenValidationResults(t, output, minInactives) + } + } +} + // JAS docker scan tests func TestAdvancedSecurityDockerScan(t *testing.T) { From bb9112ed558246f281e707493dfeb66e11228256 Mon Sep 17 00:00:00 2001 From: barv Date: Thu, 15 Aug 2024 14:53:21 +0300 Subject: [PATCH 09/32] Tests + fixes --- scans_test.go | 6 +++--- tests/utils/test_validation.go | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/scans_test.go b/scans_test.go index 015b0e00..0f62fd17 100644 --- a/scans_test.go +++ b/scans_test.go @@ -130,7 +130,7 @@ func TestDockerScan(t *testing.T) { securityTestUtils.InitSecurityTest(t, jasutils.DynamicTokenValidationMinXrayVersion) // image with inactive tokens - tokensImageToScan := "inactiveTokens:latest" + tokensImageToScan := "srmishj/inactive_tokens:latest" runDockerScanWithTokenValidation(t, testCli, tokensImageToScan, 5) } @@ -174,10 +174,10 @@ func runDockerScanWithTokenValidation(t *testing.T, testCli *coreTests.JfrogCli, if assert.NoError(t, dockerPullCommand.Run()) { defer commonTests.DeleteTestImage(t, imageTag, containerUtils.DockerClient) // Run docker scan on image - cmdArgs := []string{"docker", "scan", "--validate-secrets", imageTag, "--server-id=default", "--licenses", "--format=json", "--fail=false", "--min-severity=low", "--fixable-only"} + cmdArgs := []string{"docker", "scan", imageTag, "--validate-secrets", "--server-id=default", "--licenses", "--format=simple-json", "--fail=false", "--min-severity=low", "--fixable-only"} output := testCli.WithoutCredentials().RunCliCmdWithOutput(t, cmdArgs...) if assert.NotEmpty(t, output) { - securityTestUtils.VerifySimpleJsonScanTokenValidationResults(t, output, minInactives) + securityTestUtils.VerifyJsonScanTokenValidationResults(t, output, minInactives) } } } diff --git a/tests/utils/test_validation.go b/tests/utils/test_validation.go index 62f65a1e..469d0554 100644 --- a/tests/utils/test_validation.go +++ b/tests/utils/test_validation.go @@ -65,6 +65,20 @@ func VerifySimpleJsonScanResults(t *testing.T, content string, minViolations, mi } } +func VerifyJsonScanTokenValidationResults(t *testing.T, content string, minInactives int) { + var results formats.SimpleJsonResults + err := json.Unmarshal([]byte(content), &results) + if assert.NoError(t, err) { + count_inactives := 0 + for _, result := range results.Secrets { + if result.TokenValidation == "Inactive" { + count_inactives += 1 + } + } + assert.GreaterOrEqual(t, count_inactives, minInactives) + } +} + func VerifySimpleJsonScanTokenValidationResults(t *testing.T, content string, minInactives int) { var results formats.SimpleJsonResults err := json.Unmarshal([]byte(content), &results) From 90c1c2fc52d6be6fd89acda78f7ee4099fb34057 Mon Sep 17 00:00:00 2001 From: barv Date: Sun, 18 Aug 2024 10:37:50 +0300 Subject: [PATCH 10/32] Tests + fixes --- formats/conversion.go | 11 ++++++----- formats/simplejsonapi.go | 2 +- formats/table.go | 2 +- utils/jasutils/jasutils.go | 9 ++++++++- utils/resultstable.go | 2 +- utils/resultstable_test.go | 6 +++--- utils/resultwriter.go | 1 + 7 files changed, 21 insertions(+), 12 deletions(-) diff --git a/formats/conversion.go b/formats/conversion.go index 7012d91c..9d60a28d 100644 --- a/formats/conversion.go +++ b/formats/conversion.go @@ -1,6 +1,7 @@ package formats import ( + "github.com/jfrog/jfrog-cli-security/utils/jasutils" "strconv" "strings" ) @@ -150,13 +151,13 @@ func ConvertToSecretsTableRow(rows []SourceCodeRow, tokenValidation bool) (table secret: rows[i].Snippet, } if tokenValidation { - newRow.tokenValidation = "N/A" - newRow.metadata = "N/A" + newRow.tokenValidation = "Not a token" + newRow.tokenInfo = "No Extra Info" if rows[i].TokenValidation != "" { - newRow.tokenValidation = rows[i].TokenValidation + newRow.tokenValidation = jasutils.TokenValidationStatusColors[rows[i].TokenValidation] } - if rows[i].Metadata != "" { - newRow.metadata = rows[i].Metadata + if strings.TrimSpace(rows[i].TokenInfo) != "" { + newRow.tokenInfo = rows[i].TokenInfo } } tableRows = append(tableRows, newRow) diff --git a/formats/simplejsonapi.go b/formats/simplejsonapi.go index 12994390..a9a89c7f 100644 --- a/formats/simplejsonapi.go +++ b/formats/simplejsonapi.go @@ -69,7 +69,7 @@ type SourceCodeRow struct { Location Finding string `json:"finding,omitempty"` TokenValidation string `json:"tokenValidation,omitempty"` - Metadata string `json:"metadata,omitempty"` + TokenInfo string `json:"metadata,omitempty"` ScannerDescription string `json:"scannerDescription,omitempty"` CodeFlow [][]Location `json:"codeFlow,omitempty"` } diff --git a/formats/table.go b/formats/table.go index 90521755..1734463e 100644 --- a/formats/table.go +++ b/formats/table.go @@ -129,7 +129,7 @@ type secretsTableRow struct { lineColumn string `col-name:"Line:Column"` secret string `col-name:"Secret"` tokenValidation string `col-name:"Token Validation" omitempty:"true"` - metadata string `col-name:"Metadata" omitempty:"true"` + tokenInfo string `col-name:"Token Info" omitempty:"true"` } type iacOrSastTableRow struct { diff --git a/utils/jasutils/jasutils.go b/utils/jasutils/jasutils.go index d8c9e888..5213e260 100644 --- a/utils/jasutils/jasutils.go +++ b/utils/jasutils/jasutils.go @@ -92,7 +92,14 @@ var TokenValidationOrder = map[string]int{ "Unsupported": 3, "Unavailable": 4, "": 5, - "N/A": 6, + "Not a token": 6, +} + +var TokenValidationStatusColors = map[string]string{ + "Active": color.New(color.Red).Render("Active"), + "Inactive": color.New(color.Green).Render("Inactive"), + "Unsupported": "Unsupported", + "Unavailable": "Unavailable", } func ConvertApplicableToScore(applicability string) int { diff --git a/utils/resultstable.go b/utils/resultstable.go index 9e43a425..ab5b7b92 100644 --- a/utils/resultstable.go +++ b/utils/resultstable.go @@ -368,7 +368,7 @@ func prepareSecrets(secrets []*sarif.Run, isTable bool) ([]formats.SourceCodeRow } if tokenValidation := sarifutils.GetResultPropertyTokenValidation(secretResult); tokenValidation != "" { newRow.TokenValidation = sarifutils.GetResultPropertyTokenValidation(secretResult) - newRow.Metadata = sarifutils.GetResultPropertyMetadata(secretResult) + newRow.TokenInfo = sarifutils.GetResultPropertyMetadata(secretResult) tokenValidationActivated = true } secretsRows = append(secretsRows, newRow) diff --git a/utils/resultstable_test.go b/utils/resultstable_test.go index 09a82e07..d3aa22bc 100644 --- a/utils/resultstable_test.go +++ b/utils/resultstable_test.go @@ -1115,7 +1115,7 @@ func TestPrepareSecrets(t *testing.T) { SeverityNumValue: 11, }, TokenValidation: "", - Metadata: "", + TokenInfo: "", Finding: "secret finding", Location: formats.Location{ File: "wd/file", @@ -1132,7 +1132,7 @@ func TestPrepareSecrets(t *testing.T) { SeverityNumValue: 11, }, TokenValidation: "Inactive", - Metadata: "", + TokenInfo: "", Finding: "other secret finding", Location: formats.Location{ File: "wd/file", @@ -1149,7 +1149,7 @@ func TestPrepareSecrets(t *testing.T) { SeverityNumValue: 11, }, TokenValidation: "Active", - Metadata: "testmetadata", + TokenInfo: "testmetadata", Finding: "another secret finding", Location: formats.Location{ File: "wd/file", diff --git a/utils/resultwriter.go b/utils/resultwriter.go index dc68d2bb..65283668 100644 --- a/utils/resultwriter.go +++ b/utils/resultwriter.go @@ -159,6 +159,7 @@ func (rw *ResultsWriter) printScanResultsTables() (err error) { if err = PrintSecretsTable(rw.results.ExtendedScanResults.SecretsScanResults, rw.results.ExtendedScanResults.EntitledForJas); err != nil { return } + log.Output("This table contains multiple secret types, such as tokens, generic password, ssh keys and more, token validation is only supported on tokens.") } if shouldPrintTable(rw.subScansPreformed, IacScan, rw.scanType) { if err = PrintIacTable(rw.results.ExtendedScanResults.IacScanResults, rw.results.ExtendedScanResults.EntitledForJas); err != nil { From 17cd60f4444c4411379f301dc6a163703d025886 Mon Sep 17 00:00:00 2001 From: barv Date: Sun, 18 Aug 2024 10:48:51 +0300 Subject: [PATCH 11/32] Tests + fixes --- scans_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scans_test.go b/scans_test.go index 0f62fd17..3c296e1b 100644 --- a/scans_test.go +++ b/scans_test.go @@ -129,7 +129,7 @@ func TestDockerScan(t *testing.T) { runDockerScan(t, testCli, "busybox:1.35", "", 0, 0, 0) securityTestUtils.InitSecurityTest(t, jasutils.DynamicTokenValidationMinXrayVersion) - // image with inactive tokens + // #nosec G101 -- Image with dummy token for tests tokensImageToScan := "srmishj/inactive_tokens:latest" runDockerScanWithTokenValidation(t, testCli, tokensImageToScan, 5) } From eeebff799deda25051eef4e0c93bc22593f92587 Mon Sep 17 00:00:00 2001 From: barv Date: Sun, 18 Aug 2024 10:53:17 +0300 Subject: [PATCH 12/32] Tests + fixes --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 9afb6234..51c4f56c 100644 --- a/go.mod +++ b/go.mod @@ -116,7 +116,7 @@ require ( // replace github.com/jfrog/jfrog-cli-core/v2 => github.com/jfrog/jfrog-cli-core/v2 dev -replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go v1.28.1-0.20240814160234-e68b65d94038 +replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go v1.44.1 //replace github.com/jfrog/build-info-go => github.com/jfrog/build-info-go dev diff --git a/go.sum b/go.sum index 5b11909b..11e32e37 100644 --- a/go.sum +++ b/go.sum @@ -900,8 +900,8 @@ github.com/jfrog/jfrog-apps-config v1.0.1 h1:mtv6k7g8A8BVhlHGlSveapqf4mJfonwvXYL github.com/jfrog/jfrog-apps-config v1.0.1/go.mod h1:8AIIr1oY9JuH5dylz2S6f8Ym2MaadPLR6noCBO4C22w= github.com/jfrog/jfrog-cli-core/v2 v2.54.1 h1:oNIsqUVJ/P17qEcHgj9/c1nfO23stqqj1sHB7ldFNmQ= github.com/jfrog/jfrog-cli-core/v2 v2.54.1/go.mod h1:o8Ux0XiXWayxBXbtkMd5Vbs2YJZZDNiS9jtN6yQ4Ur8= -github.com/jfrog/jfrog-client-go v1.28.1-0.20240814160234-e68b65d94038 h1:gnltCt+/UMVI/S5Bwka5zw5VLSJlWLm309qkXd0UPos= -github.com/jfrog/jfrog-client-go v1.28.1-0.20240814160234-e68b65d94038/go.mod h1:cRCuMvRgWJ6fSdyYs1pknBin41LLcXY94UOl7KHiQ8U= +github.com/jfrog/jfrog-client-go v1.44.1 h1:Dj2+gIWMInHe7MWX3XLRhPRnlFOm7jnbCrGSgFDSMFY= +github.com/jfrog/jfrog-client-go v1.44.1/go.mod h1:cRCuMvRgWJ6fSdyYs1pknBin41LLcXY94UOl7KHiQ8U= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= From c3b1efe7913e13af29762b90e69389a695752458 Mon Sep 17 00:00:00 2001 From: barv Date: Sun, 18 Aug 2024 14:33:00 +0300 Subject: [PATCH 13/32] Tests + fixes --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 51c4f56c..18a5949c 100644 --- a/go.mod +++ b/go.mod @@ -116,7 +116,7 @@ require ( // replace github.com/jfrog/jfrog-cli-core/v2 => github.com/jfrog/jfrog-cli-core/v2 dev -replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go v1.44.1 +replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go v1.28.1-0.20240818084221-512e43045068 //replace github.com/jfrog/build-info-go => github.com/jfrog/build-info-go dev diff --git a/go.sum b/go.sum index 11e32e37..a932f5a7 100644 --- a/go.sum +++ b/go.sum @@ -900,8 +900,8 @@ github.com/jfrog/jfrog-apps-config v1.0.1 h1:mtv6k7g8A8BVhlHGlSveapqf4mJfonwvXYL github.com/jfrog/jfrog-apps-config v1.0.1/go.mod h1:8AIIr1oY9JuH5dylz2S6f8Ym2MaadPLR6noCBO4C22w= github.com/jfrog/jfrog-cli-core/v2 v2.54.1 h1:oNIsqUVJ/P17qEcHgj9/c1nfO23stqqj1sHB7ldFNmQ= github.com/jfrog/jfrog-cli-core/v2 v2.54.1/go.mod h1:o8Ux0XiXWayxBXbtkMd5Vbs2YJZZDNiS9jtN6yQ4Ur8= -github.com/jfrog/jfrog-client-go v1.44.1 h1:Dj2+gIWMInHe7MWX3XLRhPRnlFOm7jnbCrGSgFDSMFY= -github.com/jfrog/jfrog-client-go v1.44.1/go.mod h1:cRCuMvRgWJ6fSdyYs1pknBin41LLcXY94UOl7KHiQ8U= +github.com/jfrog/jfrog-client-go v1.28.1-0.20240818084221-512e43045068 h1:RuZNgGLgv1lsU40OQ04ccZh0K6wA1Ma2dO5Gy8cxdv4= +github.com/jfrog/jfrog-client-go v1.28.1-0.20240818084221-512e43045068/go.mod h1:cRCuMvRgWJ6fSdyYs1pknBin41LLcXY94UOl7KHiQ8U= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= From d4abf71b240eb897609cc45e6c3299ac9efc9f86 Mon Sep 17 00:00:00 2001 From: barv Date: Mon, 19 Aug 2024 14:14:57 +0300 Subject: [PATCH 14/32] Tests + fixes --- audit_test.go | 59 ++++++++++++++++------------------ cli/docs/flags.go | 18 +++++------ formats/conversion.go | 8 ++--- jas/common.go | 4 +-- jas/common_test.go | 34 ++++++++++++++------ scans_test.go | 40 +++++++++-------------- tests/config.go | 4 +-- tests/utils/test_validation.go | 29 +++-------------- utils/jasutils/jasutils.go | 45 +++++++++++++++++++------- utils/resultstable.go | 10 +++--- utils/resultstable_test.go | 18 ++++++++--- utils/resultwriter.go | 4 ++- xsc_test.go | 4 +-- 13 files changed, 145 insertions(+), 132 deletions(-) diff --git a/audit_test.go b/audit_test.go index 12419fb8..1d7f53b5 100644 --- a/audit_test.go +++ b/audit_test.go @@ -40,7 +40,7 @@ func TestXrayAuditNpmJson(t *testing.T) { func TestXrayAuditNpmSimpleJson(t *testing.T) { output := testAuditNpm(t, string(format.SimpleJson), true) - securityTestUtils.VerifySimpleJsonScanResults(t, output, 1, 0, 1) + securityTestUtils.VerifySimpleJsonScanResults(t, output, 1, 0, 1, 0) } func testAuditNpm(t *testing.T, format string, withVuln bool) string { @@ -72,7 +72,7 @@ func TestXrayAuditPnpmJson(t *testing.T) { func TestXrayAuditPnpmSimpleJson(t *testing.T) { output := testXrayAuditPnpm(t, string(format.SimpleJson)) - securityTestUtils.VerifySimpleJsonScanResults(t, output, 0, 1, 1) + securityTestUtils.VerifySimpleJsonScanResults(t, output, 0, 1, 1, 0) } func testXrayAuditPnpm(t *testing.T, format string) string { @@ -101,7 +101,7 @@ func TestXrayAuditYarnV2Json(t *testing.T) { func TestXrayAuditYarnV2SimpleJson(t *testing.T) { testXrayAuditYarn(t, "yarn-v3", func() { output := runXrayAuditYarnWithOutput(t, string(format.SimpleJson)) - securityTestUtils.VerifySimpleJsonScanResults(t, output, 0, 1, 1) + securityTestUtils.VerifySimpleJsonScanResults(t, output, 0, 1, 1, 0) }) } @@ -127,7 +127,7 @@ func TestXrayAuditYarnV1JsonWithoutDevDependencies(t *testing.T) { func TestXrayAuditYarnV1SimpleJson(t *testing.T) { testXrayAuditYarn(t, "yarn-v1", func() { output := runXrayAuditYarnWithOutput(t, string(format.SimpleJson)) - securityTestUtils.VerifySimpleJsonScanResults(t, output, 0, 1, 1) + securityTestUtils.VerifySimpleJsonScanResults(t, output, 0, 1, 1, 0) }) } @@ -241,7 +241,7 @@ func TestXrayAuditNugetSimpleJson(t *testing.T) { t.Run(fmt.Sprintf("projectName:%s,runInstallCommand:%t", test.projectName, runInstallCommand), func(t *testing.T) { output := testXrayAuditNuget(t, test.projectName, test.format, test.restoreTech) - securityTestUtils.VerifySimpleJsonScanResults(t, output, 0, test.minVulnerabilities, test.minLicences) + securityTestUtils.VerifySimpleJsonScanResults(t, output, 0, test.minVulnerabilities, test.minLicences, 0) }) } } @@ -272,7 +272,7 @@ func TestXrayAuditGradleJson(t *testing.T) { func TestXrayAuditGradleSimpleJson(t *testing.T) { output := testXrayAuditGradle(t, string(format.SimpleJson)) - securityTestUtils.VerifySimpleJsonScanResults(t, output, 0, 3, 3) + securityTestUtils.VerifySimpleJsonScanResults(t, output, 0, 3, 3, 0) } func testXrayAuditGradle(t *testing.T, format string) string { @@ -296,7 +296,7 @@ func TestXrayAuditMavenJson(t *testing.T) { func TestXrayAuditMavenSimpleJson(t *testing.T) { output := testXscAuditMaven(t, string(format.SimpleJson)) - securityTestUtils.VerifySimpleJsonScanResults(t, output, 0, 1, 1) + securityTestUtils.VerifySimpleJsonScanResults(t, output, 0, 1, 1, 0) } func testXscAuditMaven(t *testing.T, format string) string { @@ -340,7 +340,7 @@ func TestXrayAuditMultiProjects(t *testing.T) { 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.VerifySimpleJsonScanResults(t, output, 0, 35, 0, 0) securityTestUtils.VerifySimpleJsonJasResults(t, output, 1, 9, 6, 3, 0, 25, 2) } @@ -351,7 +351,7 @@ func TestXrayAuditPipJson(t *testing.T) { func TestXrayAuditPipSimpleJson(t *testing.T) { output := testXrayAuditPip(t, string(format.SimpleJson), "") - securityTestUtils.VerifySimpleJsonScanResults(t, output, 0, 3, 1) + securityTestUtils.VerifySimpleJsonScanResults(t, output, 0, 3, 1, 0) } func TestXrayAuditPipJsonWithRequirementsFile(t *testing.T) { @@ -361,7 +361,7 @@ func TestXrayAuditPipJsonWithRequirementsFile(t *testing.T) { func TestXrayAuditPipSimpleJsonWithRequirementsFile(t *testing.T) { output := testXrayAuditPip(t, string(format.SimpleJson), "requirements.txt") - securityTestUtils.VerifySimpleJsonScanResults(t, output, 0, 2, 0) + securityTestUtils.VerifySimpleJsonScanResults(t, output, 0, 2, 0, 0) } func testXrayAuditPip(t *testing.T, format, requirementsFile string) string { @@ -390,7 +390,7 @@ func TestXrayAuditPipenvJson(t *testing.T) { func TestXrayAuditPipenvSimpleJson(t *testing.T) { output := testXrayAuditPipenv(t, string(format.SimpleJson)) - securityTestUtils.VerifySimpleJsonScanResults(t, output, 0, 3, 1) + securityTestUtils.VerifySimpleJsonScanResults(t, output, 0, 3, 1, 0) } func testXrayAuditPipenv(t *testing.T, format string) string { @@ -414,7 +414,7 @@ func TestXrayAuditPoetryJson(t *testing.T) { func TestXrayAuditPoetrySimpleJson(t *testing.T) { output := testXrayAuditPoetry(t, string(format.SimpleJson)) - securityTestUtils.VerifySimpleJsonScanResults(t, output, 0, 3, 1) + securityTestUtils.VerifySimpleJsonScanResults(t, output, 0, 3, 1, 0) } func testXrayAuditPoetry(t *testing.T, format string) string { @@ -446,9 +446,9 @@ func addDummyPackageDescriptor(t *testing.T, hasPackageJson bool) { func TestXrayAuditNotEntitledForJas(t *testing.T) { cliToRun, cleanUp := securityTestUtils.InitTestWithMockCommandOrParams(t, getNoJasAuditMockCommand) defer cleanUp() - output := testXrayAuditJas(t, cliToRun, filepath.Join("jas", "jas"), "3") + output := testXrayAuditJas(t, cliToRun, filepath.Join("jas", "jas"), "3", false) // Verify that scan results are printed - securityTestUtils.VerifySimpleJsonScanResults(t, output, 0, 8, 0) + securityTestUtils.VerifySimpleJsonScanResults(t, output, 0, 8, 0, 0) // Verify that JAS results are not printed securityTestUtils.VerifySimpleJsonJasResults(t, output, 0, 0, 0, 0, 0, 0, 0) } @@ -470,34 +470,35 @@ 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) + output := testXrayAuditJas(t, securityTests.PlatformCli, filepath.Join("jas", "jas"), "3", false) + securityTestUtils.VerifySimpleJsonScanResults(t, output, 0, 8, 0, 0) securityTestUtils.VerifySimpleJsonJasResults(t, output, 1, 9, 6, 3, 0, 2, 2) } func TestXrayAuditJasSimpleJsonWithTokenValidation(t *testing.T) { - output := testXrayAuditJasWithTokenValidation(t, securityTests.PlatformCli, filepath.Join("jas", "jas"), "3") - securityTestUtils.VerifySimpleJsonScanTokenValidationResults(t, output, 5) + securityTestUtils.InitSecurityTest(t, jasutils.DynamicTokenValidationMinXrayVersion) + output := testXrayAuditJas(t, securityTests.PlatformCli, filepath.Join("jas", "jas"), "3", true) + securityTestUtils.VerifySimpleJsonScanResults(t, output, 0, 0, 0, 5) } func TestXrayAuditJasSimpleJsonWithOneThread(t *testing.T) { - output := testXrayAuditJas(t, securityTests.PlatformCli, filepath.Join("jas", "jas"), "1") - securityTestUtils.VerifySimpleJsonScanResults(t, output, 0, 8, 0) + output := testXrayAuditJas(t, securityTests.PlatformCli, filepath.Join("jas", "jas"), "1", false) + securityTestUtils.VerifySimpleJsonScanResults(t, output, 0, 8, 0, 0) securityTestUtils.VerifySimpleJsonJasResults(t, output, 1, 9, 6, 3, 0, 2, 2) } func TestXrayAuditJasSimpleJsonWithConfig(t *testing.T) { - output := testXrayAuditJas(t, securityTests.PlatformCli, filepath.Join("jas", "jas-config"), "3") + output := testXrayAuditJas(t, securityTests.PlatformCli, filepath.Join("jas", "jas-config"), "3", false) securityTestUtils.VerifySimpleJsonJasResults(t, output, 0, 0, 1, 3, 0, 2, 2) } func TestXrayAuditJasNoViolationsSimpleJson(t *testing.T) { - output := testXrayAuditJas(t, securityTests.PlatformCli, filepath.Join("package-managers", "npm", "npm"), "3") - securityTestUtils.VerifySimpleJsonScanResults(t, output, 0, 1, 0) + output := testXrayAuditJas(t, securityTests.PlatformCli, filepath.Join("package-managers", "npm", "npm"), "3", false) + securityTestUtils.VerifySimpleJsonScanResults(t, output, 0, 1, 0, 0) securityTestUtils.VerifySimpleJsonJasResults(t, output, 0, 0, 0, 0, 0, 0, 1) } -func testXrayAuditJas(t *testing.T, testCli *coreTests.JfrogCli, project string, threads string, validateSecrets ...bool) string { +func testXrayAuditJas(t *testing.T, testCli *coreTests.JfrogCli, project string, threads string, validateSecrets bool) string { securityTestUtils.InitSecurityTest(t, scangraph.GraphScanMinXrayVersion) tempDirPath, createTempDirCallback := coreTests.CreateTempDirWithCallbackAndAssert(t) defer createTempDirCallback() @@ -511,17 +512,13 @@ func testXrayAuditJas(t *testing.T, testCli *coreTests.JfrogCli, project string, assert.NoError(t, err) chdirCallback := clientTests.ChangeDirWithCallback(t, baseWd, tempDirPath) defer chdirCallback() - if validateSecrets[0] { - return testCli.WithoutCredentials().RunCliCmdWithOutput(t, "audit", "--validate-secrets", "--secrets", "--format="+string(format.SimpleJson), "--threads="+threads) + args := []string{"audit", "--format=" + string(format.SimpleJson), "--threads=" + threads} + if validateSecrets { + args = append(args, "--secrets", "--validate-secrets") } return testCli.WithoutCredentials().RunCliCmdWithOutput(t, "audit", "--format="+string(format.SimpleJson), "--threads="+threads) } -func testXrayAuditJasWithTokenValidation(t *testing.T, testCli *coreTests.JfrogCli, project string, threads string) string { - securityTestUtils.InitSecurityTest(t, jasutils.DynamicTokenValidationMinXrayVersion) - return testXrayAuditJas(t, testCli, project, threads, true) -} - func TestXrayAuditDetectTech(t *testing.T) { securityTestUtils.InitSecurityTest(t, scangraph.GraphScanMinXrayVersion) tempDirPath, createTempDirCallback := coreTests.CreateTempDirWithCallbackAndAssert(t) diff --git a/cli/docs/flags.go b/cli/docs/flags.go index e1d83b9f..f7ef4084 100644 --- a/cli/docs/flags.go +++ b/cli/docs/flags.go @@ -200,15 +200,14 @@ var flagsMap = map[string]components.Flag{ Stream: components.NewStringFlag(Stream, fmt.Sprintf("Xray DBSync V3 stream, Possible values are: %s.", offlineupdate.NewValidStreams().GetValidStreamsString())), Periodic: components.NewBoolFlag(Periodic, fmt.Sprintf("Set to true to get the Xray DBSync V3 Periodic Package (Use with %s flag).", Stream)), // Scan flags - SpecFlag: components.NewStringFlag(SpecFlag, "Path to a File Spec."), - scanRecursive: components.NewBoolFlag(Recursive, "Set to false if you do not wish to collect artifacts in sub-folders to be scanned by Xray.", components.WithBoolDefaultValue(true)), - scanRegexp: components.NewBoolFlag(RegexpFlag, "Set to true to use a regular expression instead of wildcards expression to collect files to scan."), - scanAnt: components.NewBoolFlag(AntFlag, "Set to true to use an ant pattern instead of wildcards expression to collect files to scan."), - Project: components.NewStringFlag(Project, "JFrog Artifactory project key."), - Watches: components.NewStringFlag(Watches, "A comma-separated list of Xray watches, to determine Xray's violations creation."), - RepoPath: components.NewStringFlag(RepoPath, "Target repo path, to enable Xray to determine watches accordingly."), - Licenses: components.NewBoolFlag(Licenses, "Set to true if you'd like to receive licenses from Xray scanning."), - SecretValidation: components.NewBoolFlag(SecretValidation, "Set to true if you want exposures scanner to validate api tokens"), + SpecFlag: components.NewStringFlag(SpecFlag, "Path to a File Spec."), + scanRecursive: components.NewBoolFlag(Recursive, "Set to false if you do not wish to collect artifacts in sub-folders to be scanned by Xray.", components.WithBoolDefaultValue(true)), + scanRegexp: components.NewBoolFlag(RegexpFlag, "Set to true to use a regular expression instead of wildcards expression to collect files to scan."), + scanAnt: components.NewBoolFlag(AntFlag, "Set to true to use an ant pattern instead of wildcards expression to collect files to scan."), + Project: components.NewStringFlag(Project, "JFrog Artifactory project key."), + Watches: components.NewStringFlag(Watches, "A comma-separated list of Xray watches, to determine Xray's violations creation."), + RepoPath: components.NewStringFlag(RepoPath, "Target repo path, to enable Xray to determine watches accordingly."), + Licenses: components.NewBoolFlag(Licenses, "Set to true if you'd like to receive licenses from Xray scanning."), OutputFormat: components.NewStringFlag( OutputFormat, "Defines the output format of the command. Acceptable values are: table, json, simple-json and sarif. Note: the json format doesn't include information about scans that are included as part of the Advanced Security package.", @@ -258,6 +257,7 @@ var flagsMap = map[string]components.Flag{ Sast: components.NewBoolFlag(Sast, fmt.Sprintf("Selective scanners mode: Execute SAST sub-scan. Can be combined with --%s, --%s and --%s.", Sca, Secrets, Iac)), Secrets: components.NewBoolFlag(Secrets, fmt.Sprintf("Selective scanners mode: Execute Secrets sub-scan. Can be combined with --%s, --%s and --%s.", Sca, Sast, Iac)), WithoutCA: components.NewBoolFlag(WithoutCA, fmt.Sprintf("Selective scanners mode: Disable Contextual Analysis scanner after SCA. Relevant only with --%s flag.", Sca)), + SecretValidation: components.NewBoolFlag(SecretValidation, fmt.Sprintf("Selective scanners mode: Execute Token validation sub-scan on secrets. Relevant only with --%s flag.", Secrets)), // Git flags InputFile: components.NewStringFlag(InputFile, "Path to an input file in YAML format contains multiple git providers. With this option, all other scm flags will be ignored and only git servers mentioned in the file will be examined.."), diff --git a/formats/conversion.go b/formats/conversion.go index 9d60a28d..7b2af6f4 100644 --- a/formats/conversion.go +++ b/formats/conversion.go @@ -151,12 +151,12 @@ func ConvertToSecretsTableRow(rows []SourceCodeRow, tokenValidation bool) (table secret: rows[i].Snippet, } if tokenValidation { - newRow.tokenValidation = "Not a token" - newRow.tokenInfo = "No Extra Info" + newRow.tokenValidation = jasutils.TokenValidationStatusForNonTokens + newRow.tokenInfo = jasutils.MissingMetadata if rows[i].TokenValidation != "" { - newRow.tokenValidation = jasutils.TokenValidationStatusColors[rows[i].TokenValidation] + newRow.tokenValidation = jasutils.TokenValidationStatus(rows[i].TokenValidation).ToString() } - if strings.TrimSpace(rows[i].TokenInfo) != "" { + if rows[i].TokenInfo != "" { newRow.tokenInfo = rows[i].TokenInfo } } diff --git a/jas/common.go b/jas/common.go index eae590d7..a03440c5 100644 --- a/jas/common.go +++ b/jas/common.go @@ -277,13 +277,13 @@ func CheckForSecretValidation(xrayManager *xray.XrayServicesManager, xrayVersion dynamicTokenVersionMismatchErr := goclientutils.ValidateMinimumVersion(goclientutils.Xray, xrayVersion, jasutils.DynamicTokenValidationMinXrayVersion) if dynamicTokenVersionMismatchErr != nil { if validateSecrets { - log.Warn("Token validation (--validate-secrets flag) is not supported in your xray version") + log.Info(fmt.Sprintf("Token validation (--validate-secrets flag) is not supported in your xray version, your xray version is %s and the minimum is %s", xrayVersion, jasutils.DynamicTokenValidationMinXrayVersion)) } return false } // Ordered By importance // first check for flag and second check for env var - if validateSecrets || strings.ToLower(os.Getenv("JF_VALIDATE_SECRETS")) == "true" { + if validateSecrets || strings.ToLower(os.Getenv(JfSecretValidationEnvVariable)) == "true" { return true } // third check for platform api diff --git a/jas/common_test.go b/jas/common_test.go index 14adf833..15d7cef2 100644 --- a/jas/common_test.go +++ b/jas/common_test.go @@ -149,19 +149,21 @@ func TestGetAnalyzerManagerEnvVariables(t *testing.T) { func TestGetAnalyzerManagerXscEnvVars(t *testing.T) { tests := []struct { - name string - msi string - technologies []techutils.Technology - expectedOutput map[string]string + name string + msi string + validateSecrets bool + technologies []techutils.Technology + expectedOutput map[string]string }{ { name: "One valid technology", msi: "msi", technologies: []techutils.Technology{techutils.Maven}, expectedOutput: map[string]string{ - JfPackageManagerEnvVariable: string(techutils.Maven), - JfLanguageEnvVariable: string(techutils.Java), - utils.JfMsiEnvVariable: "msi", + JfPackageManagerEnvVariable: string(techutils.Maven), + JfLanguageEnvVariable: string(techutils.Java), + JfSecretValidationEnvVariable: "false", + utils.JfMsiEnvVariable: "msi", }, }, { @@ -169,7 +171,8 @@ func TestGetAnalyzerManagerXscEnvVars(t *testing.T) { msi: "msi", technologies: []techutils.Technology{techutils.Maven, techutils.Npm}, expectedOutput: map[string]string{ - utils.JfMsiEnvVariable: "msi", + JfSecretValidationEnvVariable: "false", + utils.JfMsiEnvVariable: "msi", }, }, { @@ -177,13 +180,24 @@ func TestGetAnalyzerManagerXscEnvVars(t *testing.T) { msi: "msi", technologies: []techutils.Technology{}, expectedOutput: map[string]string{ - utils.JfMsiEnvVariable: "msi", + utils.JfMsiEnvVariable: "msi", + JfSecretValidationEnvVariable: "false", + }, + }, + { + name: "with validate secrets", + msi: "msi", + validateSecrets: true, + technologies: []techutils.Technology{}, + expectedOutput: map[string]string{ + utils.JfMsiEnvVariable: "msi", + JfSecretValidationEnvVariable: "true", }, }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - assert.Equal(t, test.expectedOutput, GetAnalyzerManagerXscEnvVars(test.msi, false, test.technologies...)) + assert.Equal(t, test.expectedOutput, GetAnalyzerManagerXscEnvVars(test.msi, test.validateSecrets, test.technologies...)) }) } } diff --git a/scans_test.go b/scans_test.go index 3c296e1b..e0182c65 100644 --- a/scans_test.go +++ b/scans_test.go @@ -48,7 +48,7 @@ func TestXrayBinaryScanJson(t *testing.T) { func TestXrayBinaryScanSimpleJson(t *testing.T) { output := testXrayBinaryScan(t, string(format.SimpleJson), true) - securityTestUtils.VerifySimpleJsonScanResults(t, output, 1, 1, 1) + securityTestUtils.VerifySimpleJsonScanResults(t, output, 1, 1, 1, 0) } func TestXrayBinaryScanJsonWithProgress(t *testing.T) { @@ -62,7 +62,7 @@ func TestXrayBinaryScanSimpleJsonWithProgress(t *testing.T) { callback := commonTests.MockProgressInitialization() defer callback() output := testXrayBinaryScan(t, string(format.SimpleJson), true) - securityTestUtils.VerifySimpleJsonScanResults(t, output, 1, 1, 1) + securityTestUtils.VerifySimpleJsonScanResults(t, output, 1, 1, 1, 0) } func testXrayBinaryScan(t *testing.T, format string, withViolation bool) string { @@ -118,7 +118,7 @@ func TestDockerScan(t *testing.T) { "redhat/ubi8-micro:8.4", } for _, imageName := range imagesToScan { - runDockerScan(t, testCli, imageName, watchName, 3, 3, 3) + runDockerScan(t, testCli, imageName, watchName, 3, 3, 3, 0, false) } // On Xray 3.40.3 there is a bug whereby xray fails to scan docker image with 0 vulnerabilities, @@ -126,12 +126,12 @@ func TestDockerScan(t *testing.T) { securityTestUtils.ValidateXrayVersion(t, "3.41.0") // Image with 0 vulnerabilities - runDockerScan(t, testCli, "busybox:1.35", "", 0, 0, 0) + runDockerScan(t, testCli, "busybox:1.35", "", 0, 0, 0, 0, false) securityTestUtils.InitSecurityTest(t, jasutils.DynamicTokenValidationMinXrayVersion) // #nosec G101 -- Image with dummy token for tests tokensImageToScan := "srmishj/inactive_tokens:latest" - runDockerScanWithTokenValidation(t, testCli, tokensImageToScan, 5) + runDockerScan(t, testCli, tokensImageToScan, "", 0, 0, 0, 5, true) } func initNativeDockerWithXrayTest(t *testing.T) (mockCli *coreTests.JfrogCli, cleanUp func()) { @@ -141,7 +141,7 @@ func initNativeDockerWithXrayTest(t *testing.T) (mockCli *coreTests.JfrogCli, cl return securityTestUtils.InitTestWithMockCommandOrParams(t, cli.DockerScanMockCommand) } -func runDockerScan(t *testing.T, testCli *coreTests.JfrogCli, imageName, watchName string, minViolations, minVulnerabilities, minLicenses int) { +func runDockerScan(t *testing.T, testCli *coreTests.JfrogCli, imageName, watchName string, minViolations, minVulnerabilities, minLicenses int, minInactives int, validateSecrets bool) { // Pull image from docker repo imageTag := path.Join(*securityTests.ContainerRegistry, securityTests.DockerVirtualRepo, imageName) dockerPullCommand := container.NewPullCommand(containerUtils.DockerClient) @@ -149,11 +149,19 @@ func runDockerScan(t *testing.T, testCli *coreTests.JfrogCli, imageName, watchNa if assert.NoError(t, dockerPullCommand.Run()) { defer commonTests.DeleteTestImage(t, imageTag, containerUtils.DockerClient) // Run docker scan on image - cmdArgs := []string{"docker", "scan", imageTag, "--server-id=default", "--licenses", "--format=json", "--fail=false", "--min-severity=low", "--fixable-only"} + cmdArgs := []string{"docker", "scan", imageTag, "--server-id=default", "--licenses", "--fail=false", "--min-severity=low", "--fixable-only"} + if validateSecrets { + cmdArgs = append(cmdArgs, "--validate-secrets", "--format=simple-json") + } else { + cmdArgs = append(cmdArgs, "--format=json") + } output := testCli.WithoutCredentials().RunCliCmdWithOutput(t, cmdArgs...) - if assert.NotEmpty(t, output) { + if assert.NotEmpty(t, output) && !validateSecrets { securityTestUtils.VerifyJsonScanResults(t, output, 0, minVulnerabilities, minLicenses) } + if assert.NotEmpty(t, output) && validateSecrets { + securityTestUtils.VerifySimpleJsonScanResults(t, output, 0, 0, 0, minInactives) + } // Run docker scan on image with watch if watchName == "" { return @@ -166,22 +174,6 @@ func runDockerScan(t *testing.T, testCli *coreTests.JfrogCli, imageName, watchNa } } -func runDockerScanWithTokenValidation(t *testing.T, testCli *coreTests.JfrogCli, imageName string, minInactives int) { - // Pull image from docker repo - imageTag := path.Join(*securityTests.ContainerRegistry, securityTests.DockerVirtualRepo, imageName) - dockerPullCommand := container.NewPullCommand(containerUtils.DockerClient) - dockerPullCommand.SetCmdParams([]string{"pull", imageTag}).SetImageTag(imageTag).SetRepo(securityTests.DockerVirtualRepo).SetServerDetails(securityTests.XrDetails).SetBuildConfiguration(new(build.BuildConfiguration)) - if assert.NoError(t, dockerPullCommand.Run()) { - defer commonTests.DeleteTestImage(t, imageTag, containerUtils.DockerClient) - // Run docker scan on image - cmdArgs := []string{"docker", "scan", imageTag, "--validate-secrets", "--server-id=default", "--licenses", "--format=simple-json", "--fail=false", "--min-severity=low", "--fixable-only"} - output := testCli.WithoutCredentials().RunCliCmdWithOutput(t, cmdArgs...) - if assert.NotEmpty(t, output) { - securityTestUtils.VerifyJsonScanTokenValidationResults(t, output, minInactives) - } - } -} - // JAS docker scan tests func TestAdvancedSecurityDockerScan(t *testing.T) { diff --git a/tests/config.go b/tests/config.go index 743ab542..5f6e8e3f 100644 --- a/tests/config.go +++ b/tests/config.go @@ -53,14 +53,14 @@ func init() { TestSecurity = flag.Bool("test.security", true, "Test Security") TestDockerScan = flag.Bool("test.dockerScan", false, "Test Docker scan") - JfrogUrl = flag.String("jfrog.url", "http://localhost:8081/", "JFrog platform url") + JfrogUrl = flag.String("jfrog.url", "http://localhost:8083/", "JFrog platform url") JfrogUser = flag.String("jfrog.user", "admin", "JFrog platform username") JfrogPassword = flag.String("jfrog.password", "password", "JFrog platform password") JfrogSshKeyPath = flag.String("jfrog.sshKeyPath", "", "Ssh key file path") JfrogSshPassphrase = flag.String("jfrog.sshPassphrase", "", "Ssh key passphrase") JfrogAccessToken = flag.String("jfrog.adminToken", "", "JFrog platform admin token") - ContainerRegistry = flag.String("test.containerRegistry", "localhost:8082", "Container registry") + ContainerRegistry = flag.String("test.containerRegistry", "localhost:8083", "Container registry") HideUnitTestLog = flag.Bool("test.hideUnitTestLog", false, "Hide unit tests logs and print it in a file") SkipUnitTests = flag.Bool("test.skipUnitTests", false, "Skip unit tests") diff --git a/tests/utils/test_validation.go b/tests/utils/test_validation.go index 469d0554..481e9a72 100644 --- a/tests/utils/test_validation.go +++ b/tests/utils/test_validation.go @@ -55,41 +55,20 @@ func VerifyJsonScanResults(t *testing.T, content string, minViolations, minVulne } } -func VerifySimpleJsonScanResults(t *testing.T, content string, minViolations, minVulnerabilities, minLicenses int) { +func VerifySimpleJsonScanResults(t *testing.T, content string, minViolations, minVulnerabilities, minLicenses, minInactives int) { var results formats.SimpleJsonResults err := json.Unmarshal([]byte(content), &results) if assert.NoError(t, err) { assert.GreaterOrEqual(t, len(results.SecurityViolations), minViolations) assert.GreaterOrEqual(t, len(results.Vulnerabilities), minVulnerabilities) assert.GreaterOrEqual(t, len(results.Licenses), minLicenses) - } -} - -func VerifyJsonScanTokenValidationResults(t *testing.T, content string, minInactives int) { - var results formats.SimpleJsonResults - err := json.Unmarshal([]byte(content), &results) - if assert.NoError(t, err) { - count_inactives := 0 - for _, result := range results.Secrets { - if result.TokenValidation == "Inactive" { - count_inactives += 1 - } - } - assert.GreaterOrEqual(t, count_inactives, minInactives) - } -} - -func VerifySimpleJsonScanTokenValidationResults(t *testing.T, content string, minInactives int) { - var results formats.SimpleJsonResults - err := json.Unmarshal([]byte(content), &results) - if assert.NoError(t, err) { - count_inactives := 0 + countInactives := 0 for _, result := range results.Secrets { if result.TokenValidation == "Inactive" { - count_inactives += 1 + countInactives += 1 } } - assert.GreaterOrEqual(t, count_inactives, minInactives) + assert.GreaterOrEqual(t, countInactives, minInactives) } } diff --git a/utils/jasutils/jasutils.go b/utils/jasutils/jasutils.go index 5213e260..ff0c2a24 100644 --- a/utils/jasutils/jasutils.go +++ b/utils/jasutils/jasutils.go @@ -14,6 +14,11 @@ const ( DynamicTokenValidationMinXrayVersion = "3.101.0" ) +const ( + TokenValidationStatusForNonTokens = "Not a token" + MissingMetadata = "No extra info" +) + const ( Applicability JasScanType = "Applicability" Secrets JasScanType = "Secrets" @@ -21,12 +26,35 @@ const ( Sast JasScanType = "Sast" ) +const ( + Active TokenValidationStatus = "Active" + Inactive TokenValidationStatus = "Inactive" + Unsupported TokenValidationStatus = "Unsupported" + Unavailable TokenValidationStatus = "Unavailable" + NotAToken TokenValidationStatus = TokenValidationStatusForNonTokens +) + +type TokenValidationStatus string + type JasScanType string func (jst JasScanType) String() string { return string(jst) } +func (tvs TokenValidationStatus) String() string { return string(tvs) } + +func (tvs TokenValidationStatus) ToString() string { + switch tvs { + case Active: + return color.New(color.Red).Render(tvs) + case Inactive: + return color.New(color.Green).Render(tvs) + default: + return tvs.String() + } +} + type ApplicabilityStatus string const ( @@ -88,18 +116,11 @@ var applicableMapToScore = map[string]int{ var TokenValidationOrder = map[string]int{ "Active": 1, - "Inactive": 2, - "Unsupported": 3, - "Unavailable": 4, - "": 5, - "Not a token": 6, -} - -var TokenValidationStatusColors = map[string]string{ - "Active": color.New(color.Red).Render("Active"), - "Inactive": color.New(color.Green).Render("Inactive"), - "Unsupported": "Unsupported", - "Unavailable": "Unavailable", + "Unsupported": 2, + "Unavailable": 3, + "Inactive": 4, + "Not a token": 5, + "": 6, } func ConvertApplicableToScore(applicability string) int { diff --git a/utils/resultstable.go b/utils/resultstable.go index ab5b7b92..467f9d50 100644 --- a/utils/resultstable.go +++ b/utils/resultstable.go @@ -367,8 +367,8 @@ func prepareSecrets(secrets []*sarif.Run, isTable bool) ([]formats.SourceCodeRow }, } if tokenValidation := sarifutils.GetResultPropertyTokenValidation(secretResult); tokenValidation != "" { - newRow.TokenValidation = sarifutils.GetResultPropertyTokenValidation(secretResult) - newRow.TokenInfo = sarifutils.GetResultPropertyMetadata(secretResult) + newRow.TokenValidation = strings.TrimSpace(sarifutils.GetResultPropertyTokenValidation(secretResult)) + newRow.TokenInfo = strings.TrimSpace(sarifutils.GetResultPropertyMetadata(secretResult)) tokenValidationActivated = true } secretsRows = append(secretsRows, newRow) @@ -377,10 +377,10 @@ func prepareSecrets(secrets []*sarif.Run, isTable bool) ([]formats.SourceCodeRow } sort.Slice(secretsRows, func(i, j int) bool { - if jasutils.TokenValidationOrder[secretsRows[i].TokenValidation] != jasutils.TokenValidationOrder[secretsRows[j].TokenValidation] { - return jasutils.TokenValidationOrder[secretsRows[i].TokenValidation] < jasutils.TokenValidationOrder[secretsRows[j].TokenValidation] + if secretsRows[i].SeverityNumValue != secretsRows[j].SeverityNumValue { + return secretsRows[i].SeverityNumValue > secretsRows[j].SeverityNumValue } - return secretsRows[i].SeverityNumValue > secretsRows[j].SeverityNumValue + return jasutils.TokenValidationOrder[secretsRows[i].TokenValidation] < jasutils.TokenValidationOrder[secretsRows[j].TokenValidation] }) return secretsRows, tokenValidationActivated diff --git a/utils/resultstable_test.go b/utils/resultstable_test.go index d3aa22bc..984ca419 100644 --- a/utils/resultstable_test.go +++ b/utils/resultstable_test.go @@ -1011,9 +1011,10 @@ func TestPrepareIac(t *testing.T) { func TestPrepareSecrets(t *testing.T) { testCases := []struct { - name string - input []*sarif.Run - expectedOutput []formats.SourceCodeRow + name string + isTokenValidationRun bool + input []*sarif.Run + expectedOutput []formats.SourceCodeRow }{ { name: "No Secret run", @@ -1098,7 +1099,8 @@ func TestPrepareSecrets(t *testing.T) { }, }, { - name: "Prepare Secret run - with results and tokens validation", + name: "Prepare Secret run - with results and tokens validation", + isTokenValidationRun: true, input: []*sarif.Run{ sarifutils.CreateRunWithDummyResults(sarifutils.CreateResultWithLocations("secret finding", "rule2", "note", sarifutils.CreateLocation("file://wd/file", 1, 2, 3, 4, "some-secret-snippet"))), sarifutils.CreateRunWithDummyResults( @@ -1166,8 +1168,14 @@ func TestPrepareSecrets(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - rows, _ := prepareSecrets(tc.input, false) + rows, isTokenValidation := prepareSecrets(tc.input, false) assert.ElementsMatch(t, tc.expectedOutput, rows) + if tc.isTokenValidationRun { + assert.Equal(t, isTokenValidation, true) + assert.Equal(t, "Active", rows[0].TokenValidation) + assert.Equal(t, "Inactive", rows[1].TokenValidation) + assert.Equal(t, "", rows[2].TokenValidation) + } }) } } diff --git a/utils/resultwriter.go b/utils/resultwriter.go index 65283668..e1e52b08 100644 --- a/utils/resultwriter.go +++ b/utils/resultwriter.go @@ -159,7 +159,9 @@ func (rw *ResultsWriter) printScanResultsTables() (err error) { if err = PrintSecretsTable(rw.results.ExtendedScanResults.SecretsScanResults, rw.results.ExtendedScanResults.EntitledForJas); err != nil { return } - log.Output("This table contains multiple secret types, such as tokens, generic password, ssh keys and more, token validation is only supported on tokens.") + if rw.results.ExtendedScanResults.SecretValidation && rw.results.ExtendedScanResults.EntitledForJas { + log.Output("This table contains multiple secret types, such as tokens, generic password, ssh keys and more, token validation is only supported on tokens.") + } } if shouldPrintTable(rw.subScansPreformed, IacScan, rw.scanType) { if err = PrintIacTable(rw.results.ExtendedScanResults.IacScanResults, rw.results.ExtendedScanResults.EntitledForJas); err != nil { diff --git a/xsc_test.go b/xsc_test.go index e65cf77c..0926c5dc 100644 --- a/xsc_test.go +++ b/xsc_test.go @@ -64,7 +64,7 @@ func TestXscAuditNpmSimpleJsonWithWatch(t *testing.T) { restoreFunc := initXscTest(t) defer restoreFunc() output := testAuditNpm(t, string(format.SimpleJson), true) - securityTestUtils.VerifySimpleJsonScanResults(t, output, 1, 1, 1) + securityTestUtils.VerifySimpleJsonScanResults(t, output, 1, 1, 1, 0) } func TestXscAuditMavenJson(t *testing.T) { @@ -78,7 +78,7 @@ func TestXscAuditMavenSimpleJson(t *testing.T) { restoreFunc := initXscTest(t) defer restoreFunc() output := testXscAuditMaven(t, string(format.SimpleJson)) - securityTestUtils.VerifySimpleJsonScanResults(t, output, 0, 1, 1) + securityTestUtils.VerifySimpleJsonScanResults(t, output, 0, 1, 1, 0) } func TestXscAnalyticsForAudit(t *testing.T) { From 152f30b0654e62039e37db42d7e22720c9c7b792 Mon Sep 17 00:00:00 2001 From: barv Date: Mon, 19 Aug 2024 14:27:46 +0300 Subject: [PATCH 15/32] Tests + fixes --- audit_test.go | 2 +- scans_test.go | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/audit_test.go b/audit_test.go index 1d7f53b5..d7781429 100644 --- a/audit_test.go +++ b/audit_test.go @@ -516,7 +516,7 @@ func testXrayAuditJas(t *testing.T, testCli *coreTests.JfrogCli, project string, if validateSecrets { args = append(args, "--secrets", "--validate-secrets") } - return testCli.WithoutCredentials().RunCliCmdWithOutput(t, "audit", "--format="+string(format.SimpleJson), "--threads="+threads) + return testCli.WithoutCredentials().RunCliCmdWithOutput(t, args...) } func TestXrayAuditDetectTech(t *testing.T) { diff --git a/scans_test.go b/scans_test.go index e0182c65..5d38169d 100644 --- a/scans_test.go +++ b/scans_test.go @@ -156,11 +156,11 @@ func runDockerScan(t *testing.T, testCli *coreTests.JfrogCli, imageName, watchNa cmdArgs = append(cmdArgs, "--format=json") } output := testCli.WithoutCredentials().RunCliCmdWithOutput(t, cmdArgs...) - if assert.NotEmpty(t, output) && !validateSecrets { + if assert.NotEmpty(t, output) { securityTestUtils.VerifyJsonScanResults(t, output, 0, minVulnerabilities, minLicenses) - } - if assert.NotEmpty(t, output) && validateSecrets { - securityTestUtils.VerifySimpleJsonScanResults(t, output, 0, 0, 0, minInactives) + if validateSecrets { + securityTestUtils.VerifySimpleJsonScanResults(t, output, 0, 0, 0, minInactives) + } } // Run docker scan on image with watch if watchName == "" { From f8226629f458ebbdbf22d63c06adc7d173dbde01 Mon Sep 17 00:00:00 2001 From: barv Date: Thu, 22 Aug 2024 11:32:43 +0300 Subject: [PATCH 16/32] Missing context new status --- go.mod | 2 +- go.sum | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index ddd0a3e7..fb242faa 100644 --- a/go.mod +++ b/go.mod @@ -116,7 +116,7 @@ require ( // replace github.com/jfrog/jfrog-cli-core/v2 => github.com/jfrog/jfrog-cli-core/v2 dev -// replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go dev +replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go v1.28.1-0.20240820210846-ac1bd1622d37 // replace github.com/jfrog/build-info-go => github.com/jfrog/build-info-go dev diff --git a/go.sum b/go.sum index 7b32069b..1dd31805 100644 --- a/go.sum +++ b/go.sum @@ -892,6 +892,7 @@ github.com/jfrog/archiver/v3 v3.6.1 h1:LOxnkw9pOn45DzCbZNFV6K0+6dCsQ0L8mR3ZcujO5 github.com/jfrog/archiver/v3 v3.6.1/go.mod h1:VgR+3WZS4N+i9FaDwLZbq+jeU4B4zctXL+gL4EMzfLw= github.com/jfrog/build-info-go v1.8.9-0.20240820163739-bb148903e3de h1:1nnH4GCKTXH2jhjTCONI4DMNnS8u9c0bhDFZzl6fE5g= github.com/jfrog/build-info-go v1.8.9-0.20240820163739-bb148903e3de/go.mod h1:6mdtqjREK76bHNODXakqKR/+ksJ9dvfLS7H57BZtnLY= +github.com/jfrog/build-info-go v1.9.34/go.mod h1:6mdtqjREK76bHNODXakqKR/+ksJ9dvfLS7H57BZtnLY= github.com/jfrog/froggit-go v1.16.1 h1:FBIM1qevX/ag9unfmpGzfmZ36D8ulOJ+DPTSFUk3l5U= github.com/jfrog/froggit-go v1.16.1/go.mod h1:TEJSzgiV+3D/GVGE8Y6j46ut1jrBLD1FL6WdMdKwwCE= github.com/jfrog/gofrog v1.7.5 h1:dFgtEDefJdlq9cqTRoe09RLxS5Bxbe1Ev5+E6SmZHcg= @@ -900,8 +901,10 @@ github.com/jfrog/jfrog-apps-config v1.0.1 h1:mtv6k7g8A8BVhlHGlSveapqf4mJfonwvXYL github.com/jfrog/jfrog-apps-config v1.0.1/go.mod h1:8AIIr1oY9JuH5dylz2S6f8Ym2MaadPLR6noCBO4C22w= github.com/jfrog/jfrog-cli-core/v2 v2.31.1-0.20240820213306-d507532c4863 h1:gD9gzsdmdrJZaqIJ/f16tuyyl64DPMDw2YQRGmHfooY= github.com/jfrog/jfrog-cli-core/v2 v2.31.1-0.20240820213306-d507532c4863/go.mod h1:2/Ccqq0ayMqIuH5AAoneX0CowwdrNWQcs5aKz8iDYkE= +github.com/jfrog/jfrog-cli-core/v2 v2.55.2/go.mod h1:2/Ccqq0ayMqIuH5AAoneX0CowwdrNWQcs5aKz8iDYkE= github.com/jfrog/jfrog-client-go v1.28.1-0.20240818084221-512e43045068 h1:RuZNgGLgv1lsU40OQ04ccZh0K6wA1Ma2dO5Gy8cxdv4= github.com/jfrog/jfrog-client-go v1.28.1-0.20240818084221-512e43045068/go.mod h1:cRCuMvRgWJ6fSdyYs1pknBin41LLcXY94UOl7KHiQ8U= +github.com/jfrog/jfrog-client-go v1.28.1-0.20240820210846-ac1bd1622d37/go.mod h1:f5Jfv+RGKVr4smOp4a4pxyBKdlpLG7R894kx2XW+w8c= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= From f0c3ad3096e586fb93fa57d2706469d72419d8e5 Mon Sep 17 00:00:00 2001 From: barv Date: Thu, 22 Aug 2024 11:40:33 +0300 Subject: [PATCH 17/32] Missing context new status --- go.sum | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/go.sum b/go.sum index 1dd31805..b0de99cc 100644 --- a/go.sum +++ b/go.sum @@ -890,8 +890,7 @@ github.com/jedib0t/go-pretty/v6 v6.5.9 h1:ACteMBRrrmm1gMsXe9PSTOClQ63IXDUt03H5U+ github.com/jedib0t/go-pretty/v6 v6.5.9/go.mod h1:zbn98qrYlh95FIhwwsbIip0LYpwSG8SUOScs+v9/t0E= github.com/jfrog/archiver/v3 v3.6.1 h1:LOxnkw9pOn45DzCbZNFV6K0+6dCsQ0L8mR3ZcujO5eI= github.com/jfrog/archiver/v3 v3.6.1/go.mod h1:VgR+3WZS4N+i9FaDwLZbq+jeU4B4zctXL+gL4EMzfLw= -github.com/jfrog/build-info-go v1.8.9-0.20240820163739-bb148903e3de h1:1nnH4GCKTXH2jhjTCONI4DMNnS8u9c0bhDFZzl6fE5g= -github.com/jfrog/build-info-go v1.8.9-0.20240820163739-bb148903e3de/go.mod h1:6mdtqjREK76bHNODXakqKR/+ksJ9dvfLS7H57BZtnLY= +github.com/jfrog/build-info-go v1.9.34 h1:bPnW58VpclbpBe/x8XEu/2BIviEOoJrJ5PkRRcmU3Co= github.com/jfrog/build-info-go v1.9.34/go.mod h1:6mdtqjREK76bHNODXakqKR/+ksJ9dvfLS7H57BZtnLY= github.com/jfrog/froggit-go v1.16.1 h1:FBIM1qevX/ag9unfmpGzfmZ36D8ulOJ+DPTSFUk3l5U= github.com/jfrog/froggit-go v1.16.1/go.mod h1:TEJSzgiV+3D/GVGE8Y6j46ut1jrBLD1FL6WdMdKwwCE= @@ -899,11 +898,9 @@ github.com/jfrog/gofrog v1.7.5 h1:dFgtEDefJdlq9cqTRoe09RLxS5Bxbe1Ev5+E6SmZHcg= github.com/jfrog/gofrog v1.7.5/go.mod h1:jyGiCgiqSSR7k86hcUSu67XVvmvkkgWTmPsH25wI298= github.com/jfrog/jfrog-apps-config v1.0.1 h1:mtv6k7g8A8BVhlHGlSveapqf4mJfonwvXYLipdsOFMY= github.com/jfrog/jfrog-apps-config v1.0.1/go.mod h1:8AIIr1oY9JuH5dylz2S6f8Ym2MaadPLR6noCBO4C22w= -github.com/jfrog/jfrog-cli-core/v2 v2.31.1-0.20240820213306-d507532c4863 h1:gD9gzsdmdrJZaqIJ/f16tuyyl64DPMDw2YQRGmHfooY= -github.com/jfrog/jfrog-cli-core/v2 v2.31.1-0.20240820213306-d507532c4863/go.mod h1:2/Ccqq0ayMqIuH5AAoneX0CowwdrNWQcs5aKz8iDYkE= +github.com/jfrog/jfrog-cli-core/v2 v2.55.2 h1:Pm4mY1UThSyFGklDl6O8qoJgTgH9jL3i2tor/ux+X8c= github.com/jfrog/jfrog-cli-core/v2 v2.55.2/go.mod h1:2/Ccqq0ayMqIuH5AAoneX0CowwdrNWQcs5aKz8iDYkE= -github.com/jfrog/jfrog-client-go v1.28.1-0.20240818084221-512e43045068 h1:RuZNgGLgv1lsU40OQ04ccZh0K6wA1Ma2dO5Gy8cxdv4= -github.com/jfrog/jfrog-client-go v1.28.1-0.20240818084221-512e43045068/go.mod h1:cRCuMvRgWJ6fSdyYs1pknBin41LLcXY94UOl7KHiQ8U= +github.com/jfrog/jfrog-client-go v1.28.1-0.20240820210846-ac1bd1622d37 h1:2IzCVxz1R+aZRa+/hIIAuOX4XcZ9KHr2JumRR62ctb4= github.com/jfrog/jfrog-client-go v1.28.1-0.20240820210846-ac1bd1622d37/go.mod h1:f5Jfv+RGKVr4smOp4a4pxyBKdlpLG7R894kx2XW+w8c= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= From d4467978f0676eb6d2b1de014a5dd2edeb2a8652 Mon Sep 17 00:00:00 2001 From: barv Date: Mon, 26 Aug 2024 13:05:04 +0300 Subject: [PATCH 18/32] token-validation fixes --- formats/conversion.go | 28 ++++++++++------------------ utils/jasutils/jasutils.go | 1 - utils/resultstable.go | 25 ++++++++++--------------- utils/resultstable_test.go | 3 +-- 4 files changed, 21 insertions(+), 36 deletions(-) diff --git a/formats/conversion.go b/formats/conversion.go index 7b2af6f4..459a8a2e 100644 --- a/formats/conversion.go +++ b/formats/conversion.go @@ -142,25 +142,17 @@ func ConvertToOperationalRiskViolationScanTableRow(rows []OperationalRiskViolati return } -func ConvertToSecretsTableRow(rows []SourceCodeRow, tokenValidation bool) (tableRows []secretsTableRow) { +func ConvertToSecretsTableRow(rows []SourceCodeRow) (tableRows []secretsTableRow) { for i := range rows { - newRow := secretsTableRow{ - severity: rows[i].Severity, - file: rows[i].File, - lineColumn: strconv.Itoa(rows[i].StartLine) + ":" + strconv.Itoa(rows[i].StartColumn), - secret: rows[i].Snippet, - } - if tokenValidation { - newRow.tokenValidation = jasutils.TokenValidationStatusForNonTokens - newRow.tokenInfo = jasutils.MissingMetadata - if rows[i].TokenValidation != "" { - newRow.tokenValidation = jasutils.TokenValidationStatus(rows[i].TokenValidation).ToString() - } - if rows[i].TokenInfo != "" { - newRow.tokenInfo = rows[i].TokenInfo - } - } - tableRows = append(tableRows, newRow) + tableRows = append(tableRows, secretsTableRow{ + severity: rows[i].Severity, + file: rows[i].File, + lineColumn: strconv.Itoa(rows[i].StartLine) + ":" + strconv.Itoa(rows[i].StartColumn), + secret: rows[i].Snippet, + tokenValidation: jasutils.TokenValidationStatus(rows[i].TokenValidation).ToString(), + tokenInfo: jasutils.TokenValidationStatus(rows[i].TokenInfo).String(), + }) + } return } diff --git a/utils/jasutils/jasutils.go b/utils/jasutils/jasutils.go index ff0c2a24..bdc9b21e 100644 --- a/utils/jasutils/jasutils.go +++ b/utils/jasutils/jasutils.go @@ -16,7 +16,6 @@ const ( const ( TokenValidationStatusForNonTokens = "Not a token" - MissingMetadata = "No extra info" ) const ( diff --git a/utils/resultstable.go b/utils/resultstable.go index 467f9d50..cbdef4a5 100644 --- a/utils/resultstable.go +++ b/utils/resultstable.go @@ -339,13 +339,11 @@ func PrepareLicenses(licenses []services.License) ([]formats.LicenseRow, error) // Prepare secrets for all non-table formats (without style or emoji) func PrepareSecrets(secrets []*sarif.Run) []formats.SourceCodeRow { - preparedSecrets, _ := prepareSecrets(secrets, false) - return preparedSecrets + return prepareSecrets(secrets, false) } -func prepareSecrets(secrets []*sarif.Run, isTable bool) ([]formats.SourceCodeRow, bool) { +func prepareSecrets(secrets []*sarif.Run, isTable bool) []formats.SourceCodeRow { var secretsRows []formats.SourceCodeRow - tokenValidationActivated := false for _, secretRun := range secrets { for _, secretResult := range secretRun.Results { currSeverity, err := severityutils.ParseSeverity(sarifutils.GetResultLevel(secretResult), true) @@ -354,7 +352,7 @@ func prepareSecrets(secrets []*sarif.Run, isTable bool) ([]formats.SourceCodeRow currSeverity = severityutils.Unknown } for _, location := range secretResult.Locations { - newRow := formats.SourceCodeRow{ + secretsRows = append(secretsRows, formats.SourceCodeRow{ SeverityDetails: severityutils.GetAsDetails(currSeverity, jasutils.Applicable, isTable), Finding: sarifutils.GetResultMsgText(secretResult), Location: formats.Location{ @@ -365,13 +363,10 @@ func prepareSecrets(secrets []*sarif.Run, isTable bool) ([]formats.SourceCodeRow EndColumn: sarifutils.GetLocationEndColumn(location), Snippet: sarifutils.GetLocationSnippet(location), }, - } - if tokenValidation := sarifutils.GetResultPropertyTokenValidation(secretResult); tokenValidation != "" { - newRow.TokenValidation = strings.TrimSpace(sarifutils.GetResultPropertyTokenValidation(secretResult)) - newRow.TokenInfo = strings.TrimSpace(sarifutils.GetResultPropertyMetadata(secretResult)) - tokenValidationActivated = true - } - secretsRows = append(secretsRows, newRow) + TokenValidation: sarifutils.GetResultPropertyTokenValidation(secretResult), + TokenInfo: sarifutils.GetResultPropertyMetadata(secretResult), + }, + ) } } } @@ -383,14 +378,14 @@ func prepareSecrets(secrets []*sarif.Run, isTable bool) ([]formats.SourceCodeRow return jasutils.TokenValidationOrder[secretsRows[i].TokenValidation] < jasutils.TokenValidationOrder[secretsRows[j].TokenValidation] }) - return secretsRows, tokenValidationActivated + return secretsRows } func PrintSecretsTable(secrets []*sarif.Run, entitledForSecretsScan bool) error { if entitledForSecretsScan { - secretsRows, tokenValidationActivated := prepareSecrets(secrets, true) + secretsRows := prepareSecrets(secrets, true) log.Output() - return coreutils.PrintTable(formats.ConvertToSecretsTableRow(secretsRows, tokenValidationActivated), "Secret Detection", + return coreutils.PrintTable(formats.ConvertToSecretsTableRow(secretsRows), "Secret Detection", "✨ No secrets were found ✨", false) } return nil diff --git a/utils/resultstable_test.go b/utils/resultstable_test.go index 984ca419..f06ba262 100644 --- a/utils/resultstable_test.go +++ b/utils/resultstable_test.go @@ -1168,10 +1168,9 @@ func TestPrepareSecrets(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - rows, isTokenValidation := prepareSecrets(tc.input, false) + rows := prepareSecrets(tc.input, false) assert.ElementsMatch(t, tc.expectedOutput, rows) if tc.isTokenValidationRun { - assert.Equal(t, isTokenValidation, true) assert.Equal(t, "Active", rows[0].TokenValidation) assert.Equal(t, "Inactive", rows[1].TokenValidation) assert.Equal(t, "", rows[2].TokenValidation) From ef3bec7aaacb84502128cc76d3bc9b80add7889a Mon Sep 17 00:00:00 2001 From: barv Date: Thu, 5 Sep 2024 10:38:00 +0300 Subject: [PATCH 19/32] token-validation fixes --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index c2f8c7a8..5b0ce976 100644 --- a/go.mod +++ b/go.mod @@ -116,7 +116,7 @@ require ( // replace github.com/jfrog/jfrog-cli-core/v2 => github.com/jfrog/jfrog-cli-core/v2 dev -replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go v1.28.1-0.20240820210846-ac1bd1622d37 +//replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go v1.28.1-0.20240820210846-ac1bd1622d37 // replace github.com/jfrog/build-info-go => github.com/jfrog/build-info-go dev diff --git a/go.sum b/go.sum index 8ee01027..8ebca8bf 100644 --- a/go.sum +++ b/go.sum @@ -900,8 +900,8 @@ github.com/jfrog/jfrog-apps-config v1.0.1 h1:mtv6k7g8A8BVhlHGlSveapqf4mJfonwvXYL github.com/jfrog/jfrog-apps-config v1.0.1/go.mod h1:8AIIr1oY9JuH5dylz2S6f8Ym2MaadPLR6noCBO4C22w= github.com/jfrog/jfrog-cli-core/v2 v2.55.7 h1:V4dO2FMNIH49lov3dMj3jYRg8KBTG7hyhHI8ftYByf8= github.com/jfrog/jfrog-cli-core/v2 v2.55.7/go.mod h1:DPO5BfWAeOByahFMMy+PcjmbPlcyoRy7Bf2C5sGKVi0= -github.com/jfrog/jfrog-client-go v1.28.1-0.20240820210846-ac1bd1622d37 h1:2IzCVxz1R+aZRa+/hIIAuOX4XcZ9KHr2JumRR62ctb4= -github.com/jfrog/jfrog-client-go v1.28.1-0.20240820210846-ac1bd1622d37/go.mod h1:f5Jfv+RGKVr4smOp4a4pxyBKdlpLG7R894kx2XW+w8c= +github.com/jfrog/jfrog-client-go v1.46.1 h1:ExqOF8ClOG9LO3vbm6jTIwQHHhprbu8lxB2RrM6mMI0= +github.com/jfrog/jfrog-client-go v1.46.1/go.mod h1:UCu2JNBfMp9rypEmCL84DCooG79xWIHVadZQR3Ab+BQ= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= From 11c9bc320ab94e7fb7c90c8dd868f966f8566b17 Mon Sep 17 00:00:00 2001 From: barv Date: Thu, 5 Sep 2024 10:50:12 +0300 Subject: [PATCH 20/32] token validation fixes --- go.mod | 2 +- jas/secrets/secretsscanner.go | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 5b0ce976..f0d4ce41 100644 --- a/go.mod +++ b/go.mod @@ -116,7 +116,7 @@ require ( // replace github.com/jfrog/jfrog-cli-core/v2 => github.com/jfrog/jfrog-cli-core/v2 dev -//replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go v1.28.1-0.20240820210846-ac1bd1622d37 +//replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go dev // replace github.com/jfrog/build-info-go => github.com/jfrog/build-info-go dev diff --git a/jas/secrets/secretsscanner.go b/jas/secrets/secretsscanner.go index 9d8b2320..391491b0 100644 --- a/jas/secrets/secretsscanner.go +++ b/jas/secrets/secretsscanner.go @@ -1,7 +1,6 @@ package secrets import ( - "github.com/jfrog/jfrog-cli-security/jas/external_files" "path/filepath" "strings" @@ -113,10 +112,6 @@ func (s *SecretScanManager) createConfigFile(module jfrogappsconfig.Module, excl } func (s *SecretScanManager) runAnalyzerManager() error { - external_files.SwapAnalyzerManager() - external_files.SwapScanners("ca_scanner", "applicability_scanner") - external_files.SwapScanners("secrets_scanner", "secrets_scanner") - external_files.SwapScanners("jas_scanner", "jas_scanner") return s.scanner.AnalyzerManager.Exec(s.configFileName, secretsScanCommand, filepath.Dir(s.scanner.AnalyzerManager.AnalyzerManagerFullPath), s.scanner.ServerDetails, s.scanner.EnvVars) } From 4a5b25b08a039e7d994af605827a221c44668f2b Mon Sep 17 00:00:00 2001 From: barv Date: Thu, 12 Sep 2024 12:00:32 +0300 Subject: [PATCH 21/32] token validation pr fixes + pull --- scans_test.go | 8 ++++---- xsc_test.go | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/scans_test.go b/scans_test.go index 082410ac..57010245 100644 --- a/scans_test.go +++ b/scans_test.go @@ -48,7 +48,7 @@ func TestXrayBinaryScanJson(t *testing.T) { func TestXrayBinaryScanSimpleJson(t *testing.T) { output := testXrayBinaryScan(t, string(format.SimpleJson), true) - securityTestUtils.VerifySimpleJsonScanResults(t, output, 1, 1, 1, 0) + securityTestUtils.VerifySimpleJsonScanResults(t, output, 1, 1, 1) } func TestXrayBinaryScanJsonWithProgress(t *testing.T) { @@ -62,7 +62,7 @@ func TestXrayBinaryScanSimpleJsonWithProgress(t *testing.T) { callback := commonTests.MockProgressInitialization() defer callback() output := testXrayBinaryScan(t, string(format.SimpleJson), true) - securityTestUtils.VerifySimpleJsonScanResults(t, output, 1, 1, 1, 0) + securityTestUtils.VerifySimpleJsonScanResults(t, output, 1, 1, 1) } func testXrayBinaryScan(t *testing.T, format string, withViolation bool) string { @@ -103,7 +103,7 @@ func TestDockerScanWithProgressBar(t *testing.T) { TestDockerScan(t) } -func TestDockerScanWithTokenvalidation(t *testing.T) { +func TestDockerScanWithTokenValidation(t *testing.T) { securityTestUtils.InitSecurityTest(t, jasutils.DynamicTokenValidationMinXrayVersion) testCli, cleanup := initNativeDockerWithXrayTest(t) defer cleanup() @@ -163,7 +163,7 @@ func runDockerScan(t *testing.T, testCli *coreTests.JfrogCli, imageName, watchNa if assert.NotEmpty(t, output) { securityTestUtils.VerifyJsonScanResults(t, output, 0, minVulnerabilities, minLicenses) if validateSecrets { - securityTestUtils.VerifySimpleJsonScanResults(t, output, 0, 0, 0, minInactives) + securityTestUtils.VerifySimpleJsonJasResults(t, output, 0, 0, 0, 0, 0, 0, 0, minInactives) } } // Run docker scan on image with watch diff --git a/xsc_test.go b/xsc_test.go index bb0cb0d4..c9da0e4c 100644 --- a/xsc_test.go +++ b/xsc_test.go @@ -64,7 +64,7 @@ func TestXscAuditNpmSimpleJsonWithWatch(t *testing.T) { restoreFunc := initXscTest(t) defer restoreFunc() output := testAuditNpm(t, string(format.SimpleJson), true) - securityTestUtils.VerifySimpleJsonScanResults(t, output, 1, 1, 1, 0) + securityTestUtils.VerifySimpleJsonScanResults(t, output, 1, 1, 1) } func TestXscAuditMavenJson(t *testing.T) { @@ -78,7 +78,7 @@ func TestXscAuditMavenSimpleJson(t *testing.T) { restoreFunc := initXscTest(t) defer restoreFunc() output := testXscAuditMaven(t, string(format.SimpleJson)) - securityTestUtils.VerifySimpleJsonScanResults(t, output, 0, 1, 1, 0) + securityTestUtils.VerifySimpleJsonScanResults(t, output, 0, 1, 1) } func TestXscAnalyticsForAudit(t *testing.T) { From 51ff1e121710e56a14912dcad770926dfe6d7dab Mon Sep 17 00:00:00 2001 From: barv Date: Thu, 12 Sep 2024 13:05:25 +0300 Subject: [PATCH 22/32] token validation pr fixes + pull --- scans_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scans_test.go b/scans_test.go index 57010245..a894ac93 100644 --- a/scans_test.go +++ b/scans_test.go @@ -161,9 +161,10 @@ func runDockerScan(t *testing.T, testCli *coreTests.JfrogCli, imageName, watchNa } output := testCli.WithoutCredentials().RunCliCmdWithOutput(t, cmdArgs...) if assert.NotEmpty(t, output) { - securityTestUtils.VerifyJsonScanResults(t, output, 0, minVulnerabilities, minLicenses) if validateSecrets { securityTestUtils.VerifySimpleJsonJasResults(t, output, 0, 0, 0, 0, 0, 0, 0, minInactives) + } else { + securityTestUtils.VerifyJsonScanResults(t, output, 0, minVulnerabilities, minLicenses) } } // Run docker scan on image with watch From ee3436891935f4765fd9944943fb1952bae09e1e Mon Sep 17 00:00:00 2001 From: barv Date: Thu, 12 Sep 2024 17:00:09 +0300 Subject: [PATCH 23/32] token validation pr fixes + pull --- formats/conversion.go | 4 ++-- formats/simplejsonapi.go | 11 +++++------ tests/utils/test_validation.go | 2 +- utils/resultstable.go | 15 ++++++++++++--- utils/resultstable_test.go | 33 +++++++++++++++------------------ utils/resultwriter.go | 10 ++++++++-- 6 files changed, 43 insertions(+), 32 deletions(-) diff --git a/formats/conversion.go b/formats/conversion.go index 459a8a2e..333a8587 100644 --- a/formats/conversion.go +++ b/formats/conversion.go @@ -149,8 +149,8 @@ func ConvertToSecretsTableRow(rows []SourceCodeRow) (tableRows []secretsTableRow file: rows[i].File, lineColumn: strconv.Itoa(rows[i].StartLine) + ":" + strconv.Itoa(rows[i].StartColumn), secret: rows[i].Snippet, - tokenValidation: jasutils.TokenValidationStatus(rows[i].TokenValidation).ToString(), - tokenInfo: jasutils.TokenValidationStatus(rows[i].TokenInfo).String(), + tokenValidation: jasutils.TokenValidationStatus(rows[i].Applicability.Status).ToString(), + tokenInfo: jasutils.TokenValidationStatus(rows[i].Applicability.ScannerDescription).String(), }) } diff --git a/formats/simplejsonapi.go b/formats/simplejsonapi.go index 6584271e..0365a26b 100644 --- a/formats/simplejsonapi.go +++ b/formats/simplejsonapi.go @@ -67,12 +67,11 @@ type OperationalRiskViolationRow struct { type SourceCodeRow struct { SeverityDetails Location - Finding string `json:"finding,omitempty"` - Fingerprint string `json:"fingerprint,omitempty"` - TokenValidation string `json:"tokenValidation,omitempty"` - TokenInfo string `json:"metadata,omitempty"` - ScannerDescription string `json:"scannerDescription,omitempty"` - CodeFlow [][]Location `json:"codeFlow,omitempty"` + Finding string `json:"finding,omitempty"` + Fingerprint string `json:"fingerprint,omitempty"` + Applicability *Applicability `json:"applicability,omitempty"` + ScannerDescription string `json:"scannerDescription,omitempty"` + CodeFlow [][]Location `json:"codeFlow,omitempty"` } type Location struct { diff --git a/tests/utils/test_validation.go b/tests/utils/test_validation.go index da53754b..47f89853 100644 --- a/tests/utils/test_validation.go +++ b/tests/utils/test_validation.go @@ -88,7 +88,7 @@ func VerifySimpleJsonJasResults(t *testing.T, content string, minSastViolations, } countInactives := 0 for _, result := range results.Secrets { - if result.TokenValidation == "Inactive" { + if result.Applicability.Status == "Inactive" { countInactives += 1 } } diff --git a/utils/resultstable.go b/utils/resultstable.go index dbd6b8f4..ea5469ce 100644 --- a/utils/resultstable.go +++ b/utils/resultstable.go @@ -352,6 +352,13 @@ func prepareSecrets(secrets []*sarif.Run, isTable bool) []formats.SourceCodeRow currSeverity = severityutils.Unknown } for _, location := range secretResult.Locations { + var applicability *formats.Applicability + status := sarifutils.GetResultPropertyTokenValidation(secretResult) + statusDescription := sarifutils.GetResultPropertyMetadata(secretResult) + if status != "" || statusDescription != "" { + applicability = &formats.Applicability{Status: status, + ScannerDescription: statusDescription} + } secretsRows = append(secretsRows, formats.SourceCodeRow{ SeverityDetails: severityutils.GetAsDetails(currSeverity, jasutils.Applicable, isTable), @@ -365,8 +372,7 @@ func prepareSecrets(secrets []*sarif.Run, isTable bool) []formats.SourceCodeRow EndColumn: sarifutils.GetLocationEndColumn(location), Snippet: sarifutils.GetLocationSnippet(location), }, - TokenValidation: sarifutils.GetResultPropertyTokenValidation(secretResult), - TokenInfo: sarifutils.GetResultPropertyMetadata(secretResult), + Applicability: applicability, }, ) } @@ -377,7 +383,10 @@ func prepareSecrets(secrets []*sarif.Run, isTable bool) []formats.SourceCodeRow if secretsRows[i].SeverityNumValue != secretsRows[j].SeverityNumValue { return secretsRows[i].SeverityNumValue > secretsRows[j].SeverityNumValue } - return jasutils.TokenValidationOrder[secretsRows[i].TokenValidation] < jasutils.TokenValidationOrder[secretsRows[j].TokenValidation] + if secretsRows[i].Applicability != nil && secretsRows[j].Applicability != nil { + return jasutils.TokenValidationOrder[secretsRows[i].Applicability.Status] < jasutils.TokenValidationOrder[secretsRows[j].Applicability.Status] + } + return true }) return secretsRows diff --git a/utils/resultstable_test.go b/utils/resultstable_test.go index 7ccedbfb..1eb7c05d 100644 --- a/utils/resultstable_test.go +++ b/utils/resultstable_test.go @@ -1102,12 +1102,12 @@ func TestPrepareSecrets(t *testing.T) { name: "Prepare Secret run - with results and tokens validation", isTokenValidationRun: true, input: []*sarif.Run{ - sarifutils.CreateRunWithDummyResults(sarifutils.CreateResultWithLocations("secret finding", "rule2", "note", sarifutils.CreateLocation("file://wd/file", 1, 2, 3, 4, "some-secret-snippet"))), + sarifutils.CreateRunWithDummyResults(sarifutils.CreateResultWithLocations("secret finding", "rule2", "note", sarifutils.CreateLocation("file://file", 1, 2, 3, 4, "some-secret-snippet"))), sarifutils.CreateRunWithDummyResults( - sarifutils.CreateResultWithProperties("other secret finding", "rule2", "note", map[string]string{"tokenValidation": "Inactive", "metadata": ""}, sarifutils.CreateLocation("file://wd/file", 1, 2, 3, 4, "some-secret-snippet")), + sarifutils.CreateResultWithProperties("other secret finding", "rule2", "note", map[string]string{"tokenValidation": "Inactive", "metadata": ""}, sarifutils.CreateLocation("file://file", 1, 2, 3, 4, "some-secret-snippet")), ), sarifutils.CreateRunWithDummyResults( - sarifutils.CreateResultWithProperties("another secret finding", "rule2", "note", map[string]string{"tokenValidation": "Active", "metadata": "testmetadata"}, sarifutils.CreateLocation("file://wd/file", 1, 2, 3, 4, "some-secret-snippet")), + sarifutils.CreateResultWithProperties("another secret finding", "rule2", "note", map[string]string{"tokenValidation": "Active", "metadata": "testmetadata"}, sarifutils.CreateLocation("file://file", 1, 2, 3, 4, "some-secret-snippet")), ), }, expectedOutput: []formats.SourceCodeRow{ @@ -1116,11 +1116,10 @@ func TestPrepareSecrets(t *testing.T) { Severity: "Low", SeverityNumValue: 11, }, - TokenValidation: "", - TokenInfo: "", - Finding: "secret finding", + Applicability: &formats.Applicability{Status: "", ScannerDescription: ""}, + Finding: "secret finding", Location: formats.Location{ - File: "wd/file", + File: "file", StartLine: 1, StartColumn: 2, EndLine: 3, @@ -1133,11 +1132,10 @@ func TestPrepareSecrets(t *testing.T) { Severity: "Low", SeverityNumValue: 11, }, - TokenValidation: "Inactive", - TokenInfo: "", - Finding: "other secret finding", + Applicability: &formats.Applicability{Status: "Inactive", ScannerDescription: ""}, + Finding: "other secret finding", Location: formats.Location{ - File: "wd/file", + File: "file", StartLine: 1, StartColumn: 2, EndLine: 3, @@ -1150,11 +1148,10 @@ func TestPrepareSecrets(t *testing.T) { Severity: "Low", SeverityNumValue: 11, }, - TokenValidation: "Active", - TokenInfo: "testmetadata", - Finding: "another secret finding", + Applicability: &formats.Applicability{Status: "Active", ScannerDescription: "testmetadata"}, + Finding: "another secret finding", Location: formats.Location{ - File: "wd/file", + File: "file", StartLine: 1, StartColumn: 2, EndLine: 3, @@ -1171,9 +1168,9 @@ func TestPrepareSecrets(t *testing.T) { rows := prepareSecrets(tc.input, false) assert.ElementsMatch(t, tc.expectedOutput, rows) if tc.isTokenValidationRun { - assert.Equal(t, "Active", rows[0].TokenValidation) - assert.Equal(t, "Inactive", rows[1].TokenValidation) - assert.Equal(t, "", rows[2].TokenValidation) + assert.Equal(t, "Active", rows[0].Applicability.Status) + assert.Equal(t, "Inactive", rows[1].Applicability.Status) + assert.Equal(t, (*formats.Applicability)(nil), rows[2].Applicability) } }) } diff --git a/utils/resultwriter.go b/utils/resultwriter.go index cf252f26..04542a21 100644 --- a/utils/resultwriter.go +++ b/utils/resultwriter.go @@ -750,7 +750,7 @@ func getBaseBinaryDescriptionMarkdown(subScanType SubScanType, cmdResults *Resul if len(result.Locations) > 0 { location = result.Locations[0] } - return content + getBinaryLocationMarkdownString(cmdResults.ResultType, subScanType, location) + return content + getBinaryLocationMarkdownString(cmdResults.ResultType, subScanType, location, result) } func getDockerImageTag(cmdResults *Results) string { @@ -769,7 +769,7 @@ func getDockerImageTag(cmdResults *Results) string { // * Layer: // * Filepath: // * Evidence: -func getBinaryLocationMarkdownString(commandType CommandType, subScanType SubScanType, location *sarif.Location) (content string) { +func getBinaryLocationMarkdownString(commandType CommandType, subScanType SubScanType, location *sarif.Location, result *sarif.Result) (content string) { if location == nil { return "" } @@ -791,6 +791,12 @@ func getBinaryLocationMarkdownString(commandType CommandType, subScanType SubSca if snippet := sarifutils.GetLocationSnippet(location); snippet != "" { content += fmt.Sprintf("\nEvidence: %s", snippet) } + if tokenValidation := sarifutils.GetResultPropertyTokenValidation(result); tokenValidation != "" { + content += fmt.Sprintf("\nToken Validation %s", tokenValidation) + } + if metadata := sarifutils.GetResultPropertyMetadata(result); metadata != "" { + content += fmt.Sprintf("\nMetadata %s", metadata) + } return } From 222a0297b367fe1b8c04927cc3228084de63bd2e Mon Sep 17 00:00:00 2001 From: barv Date: Thu, 12 Sep 2024 17:13:42 +0300 Subject: [PATCH 24/32] token validation fixes --- utils/resultstable_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/resultstable_test.go b/utils/resultstable_test.go index 1eb7c05d..c082f134 100644 --- a/utils/resultstable_test.go +++ b/utils/resultstable_test.go @@ -1116,7 +1116,7 @@ func TestPrepareSecrets(t *testing.T) { Severity: "Low", SeverityNumValue: 11, }, - Applicability: &formats.Applicability{Status: "", ScannerDescription: ""}, + Applicability: nil, Finding: "secret finding", Location: formats.Location{ File: "file", From 0e5823c33693c4a5ea952093772ccfe4de8a3c39 Mon Sep 17 00:00:00 2001 From: barv Date: Thu, 12 Sep 2024 17:16:54 +0300 Subject: [PATCH 25/32] token validation fixes --- jas/analyzermanager.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jas/analyzermanager.go b/jas/analyzermanager.go index 781aab9f..4222119c 100644 --- a/jas/analyzermanager.go +++ b/jas/analyzermanager.go @@ -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" From 94fdb711e5cb76ab0d24e892f50d0f795cebb181 Mon Sep 17 00:00:00 2001 From: barv Date: Thu, 12 Sep 2024 17:41:51 +0300 Subject: [PATCH 26/32] token validation fixes --- formats/conversion.go | 10 ++++++++-- formats/sarifutils/sarifutils.go | 8 -------- utils/resultstable.go | 20 ++++++++++++++++---- utils/resultwriter.go | 9 +++------ 4 files changed, 27 insertions(+), 20 deletions(-) diff --git a/formats/conversion.go b/formats/conversion.go index 333a8587..49c97e8e 100644 --- a/formats/conversion.go +++ b/formats/conversion.go @@ -144,13 +144,19 @@ func ConvertToOperationalRiskViolationScanTableRow(rows []OperationalRiskViolati func ConvertToSecretsTableRow(rows []SourceCodeRow) (tableRows []secretsTableRow) { for i := range rows { + var status string + var info string + if rows[i].Applicability != nil { + status = rows[i].Applicability.Status + info = rows[i].Applicability.ScannerDescription + } tableRows = append(tableRows, secretsTableRow{ severity: rows[i].Severity, file: rows[i].File, lineColumn: strconv.Itoa(rows[i].StartLine) + ":" + strconv.Itoa(rows[i].StartColumn), secret: rows[i].Snippet, - tokenValidation: jasutils.TokenValidationStatus(rows[i].Applicability.Status).ToString(), - tokenInfo: jasutils.TokenValidationStatus(rows[i].Applicability.ScannerDescription).String(), + tokenValidation: jasutils.TokenValidationStatus(status).ToString(), + tokenInfo: info, }) } diff --git a/formats/sarifutils/sarifutils.go b/formats/sarifutils/sarifutils.go index 336d81ae..3a5abe96 100644 --- a/formats/sarifutils/sarifutils.go +++ b/formats/sarifutils/sarifutils.go @@ -99,14 +99,6 @@ func GetResultProperty(key string, result *sarif.Result) string { return "" } -func GetResultPropertyTokenValidation(result *sarif.Result) string { - return GetResultProperty("tokenValidation", result) -} - -func GetResultPropertyMetadata(result *sarif.Result) string { - return GetResultProperty("metadata", result) -} - func GetLocationRelatedCodeFlowsFromResult(location *sarif.Location, result *sarif.Result) (codeFlows []*sarif.CodeFlow) { for _, codeFlow := range result.CodeFlows { for _, stackTrace := range codeFlow.ThreadFlows { diff --git a/utils/resultstable.go b/utils/resultstable.go index 3107c4d8..72259d5a 100644 --- a/utils/resultstable.go +++ b/utils/resultstable.go @@ -353,8 +353,8 @@ func prepareSecrets(secrets []*sarif.Run, isTable bool) []formats.SourceCodeRow } for _, location := range secretResult.Locations { var applicability *formats.Applicability - status := sarifutils.GetResultPropertyTokenValidation(secretResult) - statusDescription := sarifutils.GetResultPropertyMetadata(secretResult) + status := GetResultPropertyTokenValidation(secretResult) + statusDescription := GetResultPropertyMetadata(secretResult) if status != "" || statusDescription != "" { applicability = &formats.Applicability{Status: status, ScannerDescription: statusDescription} @@ -392,12 +392,16 @@ func prepareSecrets(secrets []*sarif.Run, isTable bool) []formats.SourceCodeRow return secretsRows } -func PrintSecretsTable(secrets []*sarif.Run, entitledForSecretsScan bool) error { +func PrintSecretsTable(secrets []*sarif.Run, entitledForSecretsScan bool, tokenValidationEnabled bool) error { if entitledForSecretsScan { secretsRows := prepareSecrets(secrets, true) log.Output() - return coreutils.PrintTable(formats.ConvertToSecretsTableRow(secretsRows), "Secret Detection", + err := coreutils.PrintTable(formats.ConvertToSecretsTableRow(secretsRows), "Secret Detection", "✨ No secrets were found ✨", false) + if err == nil && entitledForSecretsScan && tokenValidationEnabled { + log.Output("This table contains multiple secret types, such as tokens, generic password, ssh keys and more, token validation is only supported on tokens.") + } + return err } return nil } @@ -1047,6 +1051,14 @@ func GetRuleUndeterminedReason(rule *sarif.ReportingDescriptor) string { return sarifutils.GetRuleProperty("undetermined_reason", rule) } +func GetResultPropertyTokenValidation(result *sarif.Result) string { + return sarifutils.GetResultProperty("tokenValidation", result) +} + +func GetResultPropertyMetadata(result *sarif.Result) string { + return sarifutils.GetResultProperty("metadata", result) +} + func getApplicabilityStatusFromRule(rule *sarif.ReportingDescriptor) jasutils.ApplicabilityStatus { if rule.Properties["applicability"] != nil { status, ok := rule.Properties["applicability"].(string) diff --git a/utils/resultwriter.go b/utils/resultwriter.go index 04542a21..6d5ccb0e 100644 --- a/utils/resultwriter.go +++ b/utils/resultwriter.go @@ -175,12 +175,9 @@ func (rw *ResultsWriter) printScanResultsTables() (err error) { } } if shouldPrintTable(rw.subScansPreformed, SecretsScan, rw.results.ResultType) { - if err = PrintSecretsTable(rw.results.ExtendedScanResults.SecretsScanResults, rw.results.ExtendedScanResults.EntitledForJas); err != nil { + if err = PrintSecretsTable(rw.results.ExtendedScanResults.SecretsScanResults, rw.results.ExtendedScanResults.EntitledForJas, rw.results.ExtendedScanResults.SecretValidation); err != nil { return } - if rw.results.ExtendedScanResults.SecretValidation && rw.results.ExtendedScanResults.EntitledForJas { - log.Output("This table contains multiple secret types, such as tokens, generic password, ssh keys and more, token validation is only supported on tokens.") - } } if shouldPrintTable(rw.subScansPreformed, IacScan, rw.results.ResultType) { if err = PrintIacTable(rw.results.ExtendedScanResults.IacScanResults, rw.results.ExtendedScanResults.EntitledForJas); err != nil { @@ -791,10 +788,10 @@ func getBinaryLocationMarkdownString(commandType CommandType, subScanType SubSca if snippet := sarifutils.GetLocationSnippet(location); snippet != "" { content += fmt.Sprintf("\nEvidence: %s", snippet) } - if tokenValidation := sarifutils.GetResultPropertyTokenValidation(result); tokenValidation != "" { + if tokenValidation := GetResultPropertyTokenValidation(result); tokenValidation != "" { content += fmt.Sprintf("\nToken Validation %s", tokenValidation) } - if metadata := sarifutils.GetResultPropertyMetadata(result); metadata != "" { + if metadata := GetResultPropertyMetadata(result); metadata != "" { content += fmt.Sprintf("\nMetadata %s", metadata) } return From 9f62cbda1b6cdebc5c42b5660b2198b5389bbc81 Mon Sep 17 00:00:00 2001 From: barv Date: Thu, 12 Sep 2024 17:42:23 +0300 Subject: [PATCH 27/32] token validation fixes --- utils/resultstable_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/resultstable_test.go b/utils/resultstable_test.go index 4e0fd57c..2c5abb31 100644 --- a/utils/resultstable_test.go +++ b/utils/resultstable_test.go @@ -1183,7 +1183,7 @@ func TestPrepareSecrets(t *testing.T) { if tc.isTokenValidationRun { assert.Equal(t, "Active", rows[0].Applicability.Status) assert.Equal(t, "Inactive", rows[1].Applicability.Status) - assert.Equal(t, (*formats.Applicability)(nil), rows[2].Applicability) + assert.Nil(t, rows[2].Applicability) } }) } From 8d16e367999ad04abfe046b445433024d3368fc7 Mon Sep 17 00:00:00 2001 From: barv Date: Thu, 12 Sep 2024 17:49:11 +0300 Subject: [PATCH 28/32] token validation fixes --- utils/resultstable.go | 2 +- utils/resultwriter.go | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/utils/resultstable.go b/utils/resultstable.go index 72259d5a..0906c9f7 100644 --- a/utils/resultstable.go +++ b/utils/resultstable.go @@ -398,7 +398,7 @@ func PrintSecretsTable(secrets []*sarif.Run, entitledForSecretsScan bool, tokenV log.Output() err := coreutils.PrintTable(formats.ConvertToSecretsTableRow(secretsRows), "Secret Detection", "✨ No secrets were found ✨", false) - if err == nil && entitledForSecretsScan && tokenValidationEnabled { + if err == nil && tokenValidationEnabled { log.Output("This table contains multiple secret types, such as tokens, generic password, ssh keys and more, token validation is only supported on tokens.") } return err diff --git a/utils/resultwriter.go b/utils/resultwriter.go index 6d5ccb0e..9eb70064 100644 --- a/utils/resultwriter.go +++ b/utils/resultwriter.go @@ -791,9 +791,6 @@ func getBinaryLocationMarkdownString(commandType CommandType, subScanType SubSca if tokenValidation := GetResultPropertyTokenValidation(result); tokenValidation != "" { content += fmt.Sprintf("\nToken Validation %s", tokenValidation) } - if metadata := GetResultPropertyMetadata(result); metadata != "" { - content += fmt.Sprintf("\nMetadata %s", metadata) - } return } From 9e1e64862a12d6c64042f2ced62dd1b343e6be04 Mon Sep 17 00:00:00 2001 From: barv Date: Thu, 12 Sep 2024 18:24:08 +0300 Subject: [PATCH 29/32] fix token validation --- tests/utils/test_validation.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/utils/test_validation.go b/tests/utils/test_validation.go index 47f89853..c457091e 100644 --- a/tests/utils/test_validation.go +++ b/tests/utils/test_validation.go @@ -88,8 +88,10 @@ func VerifySimpleJsonJasResults(t *testing.T, content string, minSastViolations, } countInactives := 0 for _, result := range results.Secrets { - if result.Applicability.Status == "Inactive" { - countInactives += 1 + if result.Applicability != nil { + if result.Applicability.Status == "Inactive" { + countInactives += 1 + } } } assert.GreaterOrEqual(t, countInactives, minInactives) From 4a31491b273eba4d2b6bf8a9d7101b05e20b04ba Mon Sep 17 00:00:00 2001 From: barv Date: Thu, 12 Sep 2024 19:33:37 +0300 Subject: [PATCH 30/32] fix token-validation --- audit_test.go | 4 ++-- commands/audit/audit_test.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/audit_test.go b/audit_test.go index 3e40ed16..73f3b7ca 100644 --- a/audit_test.go +++ b/audit_test.go @@ -341,7 +341,7 @@ func TestXrayAuditMultiProjects(t *testing.T) { 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, 0) + securityTestUtils.VerifySimpleJsonJasResults(t, output, 1, 9, 6, 3, 0, 24, 2, 0) } func TestXrayAuditPipJson(t *testing.T) { @@ -489,7 +489,7 @@ func TestXrayAuditJasSimpleJsonWithOneThread(t *testing.T) { func TestXrayAuditJasSimpleJsonWithConfig(t *testing.T) { output := testXrayAuditJas(t, securityTests.PlatformCli, filepath.Join("jas", "jas-config"), "3", false) - securityTestUtils.VerifySimpleJsonJasResults(t, output, 0, 0, 1, 3, 1, 2, 2, 0) + securityTestUtils.VerifySimpleJsonJasResults(t, output, 0, 0, 1, 3, 1, 1, 2, 0) } func TestXrayAuditJasNoViolationsSimpleJson(t *testing.T) { diff --git a/commands/audit/audit_test.go b/commands/audit/audit_test.go index 1a1b0acc..52e24364 100644 --- a/commands/audit/audit_test.go +++ b/commands/audit/audit_test.go @@ -42,7 +42,7 @@ func TestAuditWithConfigProfile(t *testing.T) { IsDefault: false, }, expectedSastIssues: 0, - expectedSecretsIssues: 7, + expectedSecretsIssues: 16, }, { name: "Enable only sast scanner", @@ -86,7 +86,7 @@ func TestAuditWithConfigProfile(t *testing.T) { IsDefault: false, }, expectedSastIssues: 1, - expectedSecretsIssues: 7, + expectedSecretsIssues: 16, }, } From 32750387a226afd7672c3fc7efa9be6d0cf499f5 Mon Sep 17 00:00:00 2001 From: barv Date: Tue, 17 Sep 2024 12:59:16 +0300 Subject: [PATCH 31/32] pull and fix --- audit_test.go | 14 +++++++------- scans_test.go | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/audit_test.go b/audit_test.go index b25d5ae7..cd8ed215 100644 --- a/audit_test.go +++ b/audit_test.go @@ -450,7 +450,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, 0) + securityTestUtils.VerifySimpleJsonJasResults(t, output, 0, 0, 0, 0, 0, 0, 0, 0, 0) } func getNoJasAuditMockCommand() components.Command { @@ -472,30 +472,30 @@ func getNoJasAuditMockCommand() components.Command { func TestXrayAuditJasSimpleJson(t *testing.T) { output := testXrayAuditJas(t, securityTests.PlatformCli, filepath.Join("jas", "jas"), "3", false) securityTestUtils.VerifySimpleJsonScanResults(t, output, 0, 8, 0) - securityTestUtils.VerifySimpleJsonJasResults(t, output, 1, 9, 6, 3, 1, 1, 2, 0) + securityTestUtils.VerifySimpleJsonJasResults(t, output, 1, 9, 6, 3, 1, 1, 2, 0, 0) } func TestXrayAuditJasSimpleJsonWithTokenValidation(t *testing.T) { securityTestUtils.InitSecurityTest(t, jasutils.DynamicTokenValidationMinXrayVersion) output := testXrayAuditJas(t, securityTests.PlatformCli, filepath.Join("jas", "jas"), "3", true) - securityTestUtils.VerifySimpleJsonJasResults(t, output, 0, 0, 0, 0, 0, 0, 0, 5) + securityTestUtils.VerifySimpleJsonJasResults(t, output, 0, 0, 0, 0, 0, 0, 0, 0, 5) } func TestXrayAuditJasSimpleJsonWithOneThread(t *testing.T) { output := testXrayAuditJas(t, securityTests.PlatformCli, filepath.Join("jas", "jas"), "1", false) securityTestUtils.VerifySimpleJsonScanResults(t, output, 0, 8, 0) - securityTestUtils.VerifySimpleJsonJasResults(t, output, 1, 9, 6, 3, 1, 1, 2, 0) + securityTestUtils.VerifySimpleJsonJasResults(t, output, 1, 9, 6, 3, 1, 1, 2, 0, 0) } func TestXrayAuditJasSimpleJsonWithConfig(t *testing.T) { output := testXrayAuditJas(t, securityTests.PlatformCli, filepath.Join("jas", "jas-config"), "3", false) - securityTestUtils.VerifySimpleJsonJasResults(t, output, 0, 0, 1, 3, 1, 1, 2, 0) + securityTestUtils.VerifySimpleJsonJasResults(t, output, 0, 0, 1, 3, 1, 1, 2, 0, 0) } func TestXrayAuditJasNoViolationsSimpleJson(t *testing.T) { output := testXrayAuditJas(t, securityTests.PlatformCli, filepath.Join("package-managers", "npm", "npm"), "3", false) securityTestUtils.VerifySimpleJsonScanResults(t, output, 0, 1, 0) - securityTestUtils.VerifySimpleJsonJasResults(t, output, 0, 0, 0, 0, 0, 0, 1, 0) + securityTestUtils.VerifySimpleJsonJasResults(t, output, 0, 0, 0, 0, 0, 0, 1, 0, 0) } func testXrayAuditJas(t *testing.T, testCli *coreTests.JfrogCli, project string, threads string, validateSecrets bool) string { @@ -588,5 +588,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, 0) + securityTestUtils.VerifySimpleJsonJasResults(t, output, 0, 0, 0, 0, 0, 0, 0, 0, 0) } diff --git a/scans_test.go b/scans_test.go index a894ac93..1cba58c1 100644 --- a/scans_test.go +++ b/scans_test.go @@ -162,7 +162,7 @@ func runDockerScan(t *testing.T, testCli *coreTests.JfrogCli, imageName, watchNa output := testCli.WithoutCredentials().RunCliCmdWithOutput(t, cmdArgs...) if assert.NotEmpty(t, output) { if validateSecrets { - securityTestUtils.VerifySimpleJsonJasResults(t, output, 0, 0, 0, 0, 0, 0, 0, minInactives) + securityTestUtils.VerifySimpleJsonJasResults(t, output, 0, 0, 0, 0, 0, 0, 0, 0, minInactives) } else { securityTestUtils.VerifyJsonScanResults(t, output, 0, minVulnerabilities, minLicenses) } From 36117031aceb0cbbb6d15bd49bebcb799daf9c02 Mon Sep 17 00:00:00 2001 From: barv Date: Tue, 17 Sep 2024 16:15:22 +0300 Subject: [PATCH 32/32] fixes --- utils/resultstable_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/utils/resultstable_test.go b/utils/resultstable_test.go index b82f33a7..6c300cea 100644 --- a/utils/resultstable_test.go +++ b/utils/resultstable_test.go @@ -1155,7 +1155,7 @@ func TestPrepareSecrets(t *testing.T) { { SeverityDetails: formats.SeverityDetails{ Severity: "Low", - SeverityNumValue: 11, + SeverityNumValue: 13, }, Applicability: nil, Finding: "secret finding", @@ -1171,7 +1171,7 @@ func TestPrepareSecrets(t *testing.T) { { SeverityDetails: formats.SeverityDetails{ Severity: "Low", - SeverityNumValue: 11, + SeverityNumValue: 13, }, Applicability: &formats.Applicability{Status: "Inactive", ScannerDescription: ""}, Finding: "other secret finding", @@ -1187,7 +1187,7 @@ func TestPrepareSecrets(t *testing.T) { { SeverityDetails: formats.SeverityDetails{ Severity: "Low", - SeverityNumValue: 11, + SeverityNumValue: 13, }, Applicability: &formats.Applicability{Status: "Active", ScannerDescription: "testmetadata"}, Finding: "another secret finding",