Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ require (
github.com/jfrog/froggit-go v1.20.6
github.com/jfrog/gofrog v1.7.6
github.com/jfrog/jfrog-cli-artifactory v0.7.3-0.20251118100843-ac34330a70d3
github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20251023084247-a56afca52451
github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20251125083543-e689762c4ff0
github.com/jfrog/jfrog-cli-security v1.22.0
github.com/jfrog/jfrog-client-go v1.55.1-0.20251119183924-d765eb708cec
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible
Expand Down Expand Up @@ -125,14 +125,14 @@ require (
gopkg.in/warnings.v0 v0.1.2 // indirect
)

// replace github.com/jfrog/jfrog-cli-security => github.com/jfrog/jfrog-cli-security dev
replace github.com/jfrog/jfrog-cli-security => github.com/orto17/jfrog-cli-security v0.0.0-20251208182516-e1b6b0a894ba

// replace github.com/jfrog/jfrog-cli-core/v2 => github.com/jfrog/jfrog-cli-core/v2 dev

// replace github.com/jfrog/jfrog-cli-artifactory => github.com/jfrog/jfrog-cli-artifactory main

// replace github.com/jfrog/build-info-go => github.com/jfrog/build-info-go dev

// replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go dev
replace github.com/jfrog/jfrog-client-go => github.com/orto17/jfrog-client-go v0.0.0-20251208181816-46fc026428d0

// replace github.com/jfrog/froggit-go => github.com/jfrog/froggit-go master
18 changes: 6 additions & 12 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -138,12 +138,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-artifactory v0.7.3-0.20251118100843-ac34330a70d3 h1:sIjwBWBmyb7UEqP0IhQ22CWOedOPlNetyHzECS3sUyA=
github.com/jfrog/jfrog-cli-artifactory v0.7.3-0.20251118100843-ac34330a70d3/go.mod h1:3hLZrM2xT+PkIevIGret4x1xDFTaVoNu3h374QnrKyc=
github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20251023084247-a56afca52451 h1:Q0PY8VSOVsfvXzKiUnn+Rv7Ynf901QW6Wn1CbWpHBD0=
github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20251023084247-a56afca52451/go.mod h1:UOeOwEEmRIi57cRwghN5OBVoqkJieYQQfLpeqw8Yv38=
github.com/jfrog/jfrog-cli-security v1.22.0 h1:KNovA+BA1IpE0c0jI6jWF33fOimgylR9a7T84ZmgNJI=
github.com/jfrog/jfrog-cli-security v1.22.0/go.mod h1:uoACrGyWZViNPU0STC0fF38bVKtNXjm3hzWW/DKI0DY=
github.com/jfrog/jfrog-client-go v1.55.1-0.20251119183924-d765eb708cec h1:tNfeGi/2FuxIUSi8urFZuqa33grynAHwLRH6iIK/DB0=
github.com/jfrog/jfrog-client-go v1.55.1-0.20251119183924-d765eb708cec/go.mod h1:ureS+L3wNs0qYUBSwH8C9PjwnraTX9ibZu7JkaqjO/E=
github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20251125083543-e689762c4ff0 h1:EsasTBE5i2MyCESS/icZxKIlObpGiOyW9K67MAaEWco=
github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20251125083543-e689762c4ff0/go.mod h1:d9aADumiyjCBvZLffp8wldvP9XFHxcvk2PoOSUYms2g=
github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c=
github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo=
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible h1:jdpOPRN1zP63Td1hDQbZW73xKmzDvZHzVdNYxhnTMDA=
Expand Down Expand Up @@ -208,6 +204,10 @@ github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw=
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A=
github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k=
github.com/orto17/jfrog-cli-security v0.0.0-20251208182516-e1b6b0a894ba h1:oEqOkSwUlIdE3bcfsJPVf4RHtbF5r+IBGMFuo3ITdSY=
github.com/orto17/jfrog-cli-security v0.0.0-20251208182516-e1b6b0a894ba/go.mod h1:/TFG/WM+DREj28OeYNEpmfc1e+glP1gMUHad9STq7RA=
github.com/orto17/jfrog-client-go v0.0.0-20251208181816-46fc026428d0 h1:bBV6/LKY6EMb/eGhCA67CAKTOsrepjvBXt+H667I14g=
github.com/orto17/jfrog-client-go v0.0.0-20251208181816-46fc026428d0/go.mod h1:ureS+L3wNs0qYUBSwH8C9PjwnraTX9ibZu7JkaqjO/E=
github.com/owenrumney/go-sarif/v3 v3.2.3 h1:n6mdX5ugKwCrZInvBsf6WumXmpAe3mbmQXgkXlIq34U=
github.com/owenrumney/go-sarif/v3 v3.2.3/go.mod h1:1bV7t8SZg7pX41spaDkEUs8/yEjzk9JapztMoX1XNjg=
github.com/package-url/packageurl-go v0.1.3 h1:4juMED3hHiz0set3Vq3KeQ75KD1avthoXLtmE3I0PLs=
Expand Down Expand Up @@ -313,8 +313,6 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04=
golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0=
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546 h1:mgKeJMpvi0yx/sU5GsxQ7p6s2wtOnGAHZWCHUM4KGzY=
Expand All @@ -337,8 +335,6 @@ golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
golang.org/x/net v0.45.0 h1:RLBg5JKixCy82FtLJpeNlVM0nrSqpCRYzVU1n8kj0tM=
golang.org/x/net v0.45.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY=
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
Expand Down Expand Up @@ -401,8 +397,6 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
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.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
Expand Down
108 changes: 45 additions & 63 deletions scanpullrequest/scanpullrequest.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,18 @@ import (
"sort"
"strings"

"github.com/jfrog/frogbot/v2/utils"
"github.com/jfrog/frogbot/v2/utils/issues"
"github.com/jfrog/froggit-go/vcsclient"
"github.com/jfrog/froggit-go/vcsutils"
"github.com/jfrog/jfrog-cli-security/utils/formats"
"github.com/jfrog/jfrog-cli-security/utils/formats/violationutils"
"github.com/jfrog/jfrog-cli-security/utils/jasutils"
"github.com/jfrog/jfrog-cli-security/utils/results"
"github.com/jfrog/jfrog-cli-security/utils/results/conversion"
"github.com/jfrog/jfrog-cli-security/utils/xsc"
"github.com/jfrog/jfrog-client-go/utils/log"
"github.com/owenrumney/go-sarif/v3/pkg/report/v210/sarif"

"github.com/jfrog/frogbot/v2/utils"
"github.com/jfrog/frogbot/v2/utils/issues"
)

const (
Expand Down Expand Up @@ -278,7 +279,7 @@ func auditPullRequestSourceCode(repoConfig *utils.Repository, scanDetails *utils
}

// Convert to issues
if issues, e := scanResultsToIssuesCollection(scanResults, repoConfig.AllowedLicenses, workingDirs...); e == nil {
if issues, e := scanResultsToIssuesCollection(scanResults, workingDirs...); e == nil {
issuesCollection = issues
return
} else {
Expand Down Expand Up @@ -308,109 +309,91 @@ func filterOutFailedScansIfAllowPartialResultsEnabled(targetResults, sourceResul
targetResult := targetResults.Targets[idx]
sourceResult := sourceResults.Targets[idx]

filterOutScaResultsIfScanFailed(targetResult, sourceResult)
filterJasResultsIfScanFailed(targetResult, sourceResult, jasutils.Applicability)
filterJasResultsIfScanFailed(targetResult, sourceResult, jasutils.Secrets)
filterJasResultsIfScanFailed(targetResult, sourceResult, jasutils.IaC)
filterJasResultsIfScanFailed(targetResult, sourceResult, jasutils.Sast)
filterOutScaResultsIfScanFailed(targetResult, sourceResult, sourceResults.Violations)
filterJasResultsIfScanFailed(targetResult, sourceResult, results.CmdStepContextualAnalysis)
filterJasResultsIfScanFailed(targetResult, sourceResult, results.CmdStepSecrets)
filterJasResultsIfScanFailed(targetResult, sourceResult, results.CmdStepIaC)
filterJasResultsIfScanFailed(targetResult, sourceResult, results.CmdStepSast)
}
return nil
}

func filterJasResultsIfScanFailed(targetResult, sourceResult *results.TargetResults, scanType jasutils.JasScanType) {
switch scanType {
case jasutils.Applicability:
if isJasScanFailedInSourceOrTarget(sourceResult.JasResults.ApplicabilityScanResults, targetResult.JasResults.ApplicabilityScanResults) {
log.Debug(fmt.Sprintf(vulnerabilitiesFilteringErrorMessage, scanType.String()))
func filterJasResultsIfScanFailed(targetResult, sourceResult *results.TargetResults, cmdStep results.SecurityCommandStep) {
sourceResults := []*results.TargetResults{sourceResult}
targetResults := []*results.TargetResults{targetResult}
switch cmdStep {
case results.CmdStepContextualAnalysis:
if isScanFailedInSourceOrTarget(sourceResults, targetResults, cmdStep) {
log.Debug(fmt.Sprintf(vulnerabilitiesFilteringErrorMessage, cmdStep))
sourceResult.JasResults.ApplicabilityScanResults = nil
}
case jasutils.Secrets:
if isJasScanFailedInSourceOrTarget(sourceResult.JasResults.JasVulnerabilities.SecretsScanResults, targetResult.JasResults.JasVulnerabilities.SecretsScanResults) {
log.Debug(fmt.Sprintf(vulnerabilitiesFilteringErrorMessage, scanType.String()))
case results.CmdStepSecrets:
if isScanFailedInSourceOrTarget(sourceResults, targetResults, cmdStep) {
log.Debug(fmt.Sprintf(vulnerabilitiesFilteringErrorMessage, cmdStep))
sourceResult.JasResults.JasVulnerabilities.SecretsScanResults = nil
}

if (sourceResult.JasResults.JasViolations.SecretsScanResults != nil || targetResult.JasResults.JasViolations.SecretsScanResults != nil) && isJasScanFailedInSourceOrTarget(sourceResult.JasResults.JasViolations.SecretsScanResults, targetResult.JasResults.JasViolations.SecretsScanResults) {
log.Debug(fmt.Sprintf(violationsFilteringErrorMessage, scanType.String()))
if (sourceResult.JasResults.JasViolations.SecretsScanResults != nil || targetResult.JasResults.JasViolations.SecretsScanResults != nil) &&
isScanFailedInSourceOrTarget(sourceResults, targetResults, cmdStep) {
log.Debug(fmt.Sprintf(violationsFilteringErrorMessage, cmdStep))
sourceResult.JasResults.JasViolations.SecretsScanResults = nil
}
case jasutils.IaC:
if isJasScanFailedInSourceOrTarget(sourceResult.JasResults.JasVulnerabilities.IacScanResults, targetResult.JasResults.JasVulnerabilities.IacScanResults) {
log.Debug(fmt.Sprintf(vulnerabilitiesFilteringErrorMessage, scanType.String()))
case results.CmdStepIaC:
if isScanFailedInSourceOrTarget(sourceResults, targetResults, cmdStep) {
log.Debug(fmt.Sprintf(vulnerabilitiesFilteringErrorMessage, cmdStep))
sourceResult.JasResults.JasVulnerabilities.IacScanResults = nil
}

if (sourceResult.JasResults.JasViolations.IacScanResults != nil || targetResult.JasResults.JasViolations.IacScanResults != nil) && isJasScanFailedInSourceOrTarget(sourceResult.JasResults.JasViolations.IacScanResults, targetResult.JasResults.JasViolations.IacScanResults) {
log.Debug(fmt.Sprintf(violationsFilteringErrorMessage, scanType.String()))
if (sourceResult.JasResults.JasViolations.IacScanResults != nil || targetResult.JasResults.JasViolations.IacScanResults != nil) && isScanFailedInSourceOrTarget(sourceResults, targetResults, cmdStep) {
log.Debug(fmt.Sprintf(violationsFilteringErrorMessage, cmdStep))
sourceResult.JasResults.JasViolations.IacScanResults = nil
}
case jasutils.Sast:
if isJasScanFailedInSourceOrTarget(sourceResult.JasResults.JasVulnerabilities.SastScanResults, targetResult.JasResults.JasVulnerabilities.SastScanResults) {
log.Debug(fmt.Sprintf(vulnerabilitiesFilteringErrorMessage, scanType.String()))
case results.CmdStepSast:
if isScanFailedInSourceOrTarget(sourceResults, targetResults, cmdStep) {
log.Debug(fmt.Sprintf(vulnerabilitiesFilteringErrorMessage, cmdStep))
sourceResult.JasResults.JasVulnerabilities.SastScanResults = nil
}

if (sourceResult.JasResults.JasViolations.SastScanResults != nil || targetResult.JasResults.JasViolations.SastScanResults != nil) && isJasScanFailedInSourceOrTarget(sourceResult.JasResults.JasViolations.SastScanResults, targetResult.JasResults.JasViolations.SastScanResults) {
log.Debug(fmt.Sprintf(violationsFilteringErrorMessage, scanType.String()))
if (sourceResult.JasResults.JasViolations.SastScanResults != nil || targetResult.JasResults.JasViolations.SastScanResults != nil) && isScanFailedInSourceOrTarget(sourceResults, targetResults, cmdStep) {
log.Debug(fmt.Sprintf(violationsFilteringErrorMessage, cmdStep))
sourceResult.JasResults.JasViolations.SastScanResults = nil
}
}
}

func isJasScanFailedInSourceOrTarget(sourceResults, targetResults []results.ScanResult[[]*sarif.Run]) bool {
func isScanFailedInSourceOrTarget(sourceResults, targetResults []*results.TargetResults, step results.SecurityCommandStep) bool {
for _, scanResult := range sourceResults {
if scanResult.StatusCode != 0 {
if scanResult.ResultsStatus.IsScanFailed(step) {
return true
}
}

for _, scanResult := range targetResults {
if scanResult.StatusCode != 0 {
if scanResult.ResultsStatus.IsScanFailed(step) {
return true
}
}
return false
}

func filterOutScaResultsIfScanFailed(targetResult, sourceResult *results.TargetResults) {
func filterOutScaResultsIfScanFailed(targetResult, sourceResult *results.TargetResults, sourceViolations *violationutils.Violations) {
// Filter out new Sca results
if sourceResult.ScaResults.ScanStatusCode != 0 || targetResult.ScaResults.ScanStatusCode != 0 {
var statusCode int
if sourceResult.ResultsStatus.IsScanFailed(results.CmdStepSca) || targetResult.ResultsStatus.IsScanFailed(results.CmdStepSca) {
var statusCode *int
var errorSource string
if sourceResult.ScaResults.ScanStatusCode != 0 {
statusCode = sourceResult.ScaResults.ScanStatusCode
if sourceResult.ResultsStatus.IsScanFailed(results.CmdStepSca) {
statusCode = sourceResult.ResultsStatus.ScaScanStatusCode
errorSource = "source"
} else {
statusCode = targetResult.ScaResults.ScanStatusCode
statusCode = targetResult.ResultsStatus.ScaScanStatusCode
errorSource = "target"
}
log.Debug(fmt.Sprintf("Sca scan on %s code has completed with errors (status %d). Sca vulnerability results will be removed from final report", errorSource, statusCode))
sourceResult.ScaResults.Sbom = nil
if sourceResult.ScaResults.Violations != nil {
if sourceViolations != nil && sourceViolations.Sca != nil {
log.Debug(fmt.Sprintf("Sca scan on %s has completed with errors (status %d). Sca violations results will be removed from final report", errorSource, statusCode))
sourceResult.ScaResults.Violations = nil
sourceViolations.Sca = nil
}
}

// Note: Although we have a slice on ScanResults in DeprecatedXrayResults, in fact there is only a single entry
hasScaFailure := false
for _, deprecatedScaResult := range targetResult.ScaResults.DeprecatedXrayResults {
if deprecatedScaResult.StatusCode != 0 {
hasScaFailure = true
break
}
}
for _, deprecatedScaResult := range sourceResult.ScaResults.DeprecatedXrayResults {
if deprecatedScaResult.StatusCode != 0 {
hasScaFailure = true
break
}
}
if hasScaFailure {
log.Debug("Sca scan has completed with errors. Sca vulnerabilities and violations results will be removed from final report")
// Violations are being filtered as well as they are included in the DeprecatedXrayResults
sourceResult.ScaResults.DeprecatedXrayResults = nil
}
}

// Sorts the Targets slice in both targetResults and sourceResults
Expand All @@ -434,11 +417,10 @@ func sortTargetsByPhysicalLocation(targetResults, sourceResults *results.Securit
return nil
}

func scanResultsToIssuesCollection(scanResults *results.SecurityCommandResults, allowedLicenses []string, workingDirs ...string) (issuesCollection *issues.ScansIssuesCollection, err error) {
func scanResultsToIssuesCollection(scanResults *results.SecurityCommandResults, workingDirs ...string) (issuesCollection *issues.ScansIssuesCollection, err error) {
simpleJsonResults, err := conversion.NewCommandResultsConvertor(conversion.ResultConvertParams{
IncludeVulnerabilities: scanResults.IncludesVulnerabilities(),
HasViolationContext: scanResults.HasViolationContext(),
AllowedLicenses: allowedLicenses,
IncludeLicenses: true,
SimplifiedOutput: true,
}).ConvertToSimpleJson(scanResults)
Expand Down
Loading
Loading