diff --git a/formats/sarifutils/sarifutils.go b/formats/sarifutils/sarifutils.go index 6b183cb5..baf3a066 100644 --- a/formats/sarifutils/sarifutils.go +++ b/formats/sarifutils/sarifutils.go @@ -2,6 +2,7 @@ package sarifutils import ( "fmt" + "github.com/jfrog/jfrog-cli-security/utils/jasutils" "path/filepath" "strings" @@ -419,3 +420,12 @@ func GetRulesPropertyCount(property, value string, runs ...*sarif.Run) (count in } return } + +func GetResultFingerprint(result *sarif.Result) string { + if result.Fingerprints != nil { + if value, ok := result.Fingerprints[jasutils.SastFingerprintKey].(string); ok { + return value + } + } + return "" +} diff --git a/formats/sarifutils/sarifutils_test.go b/formats/sarifutils/sarifutils_test.go index 6363b515..69c54723 100644 --- a/formats/sarifutils/sarifutils_test.go +++ b/formats/sarifutils/sarifutils_test.go @@ -1,6 +1,7 @@ package sarifutils import ( + "github.com/jfrog/jfrog-cli-security/utils/jasutils" "path/filepath" "testing" @@ -615,3 +616,30 @@ func TestGetInvocationWorkingDirectory(t *testing.T) { assert.Equal(t, test.expectedOutput, GetInvocationWorkingDirectory(test.invocation)) } } + +func TestGetResultFingerprint(t *testing.T) { + tests := []struct { + name string + result *sarif.Result + expectedOutput string + }{ + { + name: "No results", + result: &sarif.Result{}, + expectedOutput: "", + }, + { + name: "Empty fingerprint field in the result", + result: CreateResultWithLocations("msg", "rule", "level"), + expectedOutput: "", + }, + { + name: "Results with fingerprint field", + result: CreateDummyResultWithFingerprint("some_markdown", "masg", jasutils.SastFingerprintKey, "sast_fingerprint"), + expectedOutput: "sast_fingerprint", + }, + } + for _, test := range tests { + assert.Equal(t, test.expectedOutput, GetResultFingerprint(test.result)) + } +} diff --git a/formats/sarifutils/test_sarifutils.go b/formats/sarifutils/test_sarifutils.go index 6848849a..8ae18413 100644 --- a/formats/sarifutils/test_sarifutils.go +++ b/formats/sarifutils/test_sarifutils.go @@ -1,6 +1,8 @@ package sarifutils -import "github.com/owenrumney/go-sarif/v2/sarif" +import ( + "github.com/owenrumney/go-sarif/v2/sarif" +) func CreateRunWithDummyResultsInWd(wd string, results ...*sarif.Result) *sarif.Run { return createRunWithDummyResults("", results...).WithInvocations([]*sarif.Invocation{sarif.NewInvocation().WithWorkingDirectory(sarif.NewSimpleArtifactLocation(wd))}) diff --git a/formats/simplejsonapi.go b/formats/simplejsonapi.go index 26ec121b..e64ee4fa 100644 --- a/formats/simplejsonapi.go +++ b/formats/simplejsonapi.go @@ -68,6 +68,7 @@ type SourceCodeRow struct { SeverityDetails Location Finding string `json:"finding,omitempty"` + Fingerprint string `json:"fingerprint,omitempty"` ScannerDescription string `json:"scannerDescription,omitempty"` CodeFlow [][]Location `json:"codeFlow,omitempty"` } diff --git a/utils/jasutils/jasutils.go b/utils/jasutils/jasutils.go index a9f83170..36b46702 100644 --- a/utils/jasutils/jasutils.go +++ b/utils/jasutils/jasutils.go @@ -33,6 +33,8 @@ const ( NotScanned ApplicabilityStatus = "" ) +const SastFingerprintKey = "precise_sink_and_sink_function" + func (as ApplicabilityStatus) String() string { return string(as) } diff --git a/utils/resultstable.go b/utils/resultstable.go index 06623eac..7d6c7863 100644 --- a/utils/resultstable.go +++ b/utils/resultstable.go @@ -356,6 +356,7 @@ func prepareSecrets(secrets []*sarif.Run, isTable bool) []formats.SourceCodeRow formats.SourceCodeRow{ SeverityDetails: severityutils.GetAsDetails(currSeverity, jasutils.Applicable, isTable), Finding: sarifutils.GetResultMsgText(secretResult), + Fingerprint: sarifutils.GetResultFingerprint(secretResult), Location: formats.Location{ File: sarifutils.GetRelativeLocationFileName(location, secretRun.Invocations), StartLine: sarifutils.GetLocationStartLine(location), @@ -410,6 +411,7 @@ func prepareIacs(iacs []*sarif.Run, isTable bool) []formats.SourceCodeRow { formats.SourceCodeRow{ SeverityDetails: severityutils.GetAsDetails(currSeverity, jasutils.Applicable, isTable), Finding: sarifutils.GetResultMsgText(iacResult), + Fingerprint: sarifutils.GetResultFingerprint(iacResult), ScannerDescription: scannerDescription, Location: formats.Location{ File: sarifutils.GetRelativeLocationFileName(location, iacRun.Invocations), @@ -466,6 +468,7 @@ func prepareSast(sasts []*sarif.Run, isTable bool) []formats.SourceCodeRow { SeverityDetails: severityutils.GetAsDetails(currSeverity, jasutils.Applicable, isTable), ScannerDescription: scannerDescription, Finding: sarifutils.GetResultMsgText(sastResult), + Fingerprint: sarifutils.GetResultFingerprint(sastResult), Location: formats.Location{ File: sarifutils.GetRelativeLocationFileName(location, sastRun.Invocations), StartLine: sarifutils.GetLocationStartLine(location),