From ccfdd7ddb1b3ce75dd0d18b717e16421c8839289 Mon Sep 17 00:00:00 2001 From: Jason Luong Date: Wed, 18 Oct 2023 11:10:30 +0100 Subject: [PATCH 1/9] feat: add OSS issue types --- internal/lsp/message_types.go | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/internal/lsp/message_types.go b/internal/lsp/message_types.go index f1377de08..b83eef582 100644 --- a/internal/lsp/message_types.go +++ b/internal/lsp/message_types.go @@ -1032,6 +1032,33 @@ type ScanIssue struct { // TODO - convert this to a generic type AdditionalData any `json:"additionalData,omitempty"` } +// Snyk Open Source +type OssIssueData struct { + License string `json:"license,omitempty"` + Identifiers OssIdentifiers `json:"identifiers,omitempty"` + Description string `json:"description"` + Language string `json:"language"` + PackageManager string `json:"packageManager"` + PackageName string `json:"packageName"` + Name string `json:"name"` + Version string `json:"version"` + Exploit string `json:"exploit,omitempty"` + CVSSv3 string `json:"CVSSv3,omitempty"` + CvssScore string `json:"cvssScore,omitempty"` + FixedIn []string `json:"fixedIn,omitempty"` + From []string `json:"from"` + UpgradePath []string `json:"upgradePath"` + IsPatchable bool `json:"isPatchable"` + IsUpgradable bool `json:"isUpgradable"` + ProjectName string `json:"projectName"` + DisplayTargetFile string `json:"displayTargetFile"` +} + +type OssIdentifiers struct { + CWE []string `json:"CWE,omitempty"` + CVE []string `json:"CVE,omitempty"` +} + type CodeIssueData struct { Message string `json:"message"` LeadURL string `json:"leadURL,omitempty"` From 75da19e369d12abb601e55b9836fdd60d9118ebb Mon Sep 17 00:00:00 2001 From: Jason Luong Date: Wed, 18 Oct 2023 11:10:53 +0100 Subject: [PATCH 2/9] chore: add failing test --- .../server/notification/scan_notifier_test.go | 100 ++++++++++++++++++ 1 file changed, 100 insertions(+) diff --git a/application/server/notification/scan_notifier_test.go b/application/server/notification/scan_notifier_test.go index 96d51aae4..76047339e 100644 --- a/application/server/notification/scan_notifier_test.go +++ b/application/server/notification/scan_notifier_test.go @@ -208,6 +208,106 @@ func Test_SendSuccess_SendsForAllEnabledProducts(t *testing.T) { } } +func Test_SendSuccess_SendsForOpenSource(t *testing.T) { + testutil.UnitTest(t) + + mockNotifier := notification.NewMockNotifier() + scanNotifier, _ := notification2.NewScanNotifier(mockNotifier) + + const folderPath = "/test/oss/folderPath" + + expectedUIScanIssue := []lsp2.ScanIssue{ + { + Id: "ossID", + Title: "ossTitle", + Severity: "critical", + FilePath: "ossAffectedFilePath", + AdditionalData: lsp2.OssIssueData{ + License: "additionalData.License", + Identifiers: lsp2.OssIdentifiers{ + CWE: []string{"789"}, + CVE: []string{"123"}, + }, + Description: "OSS description", + Language: "additionalData.Language", + PackageManager: "additionalData.PackageManager", + PackageName: "additionalData.PackageName", + Name: "additionalData.Name", + Version: "additionalData.Version", + Exploit: "additionalData.Exploit", + CVSSv3: "additionalData.CVSSv3", + CvssScore: "1.1", + FixedIn: []string{"1.1.1"}, + From: []string{"1.1.1"}, + UpgradePath: []string{"1.1.1"}, + IsPatchable: true, + IsUpgradable: true, + ProjectName: "additionalData.ProjectName", + DisplayTargetFile: "additionalData.DisplayTargetFile", + }, + }, + } + + issues := []snyk.Issue{ + { // OSS issue + ID: "ossID", + Severity: snyk.Critical, + IssueType: 1, + Range: snyk.Range{ + Start: snyk.Position{ + Line: 1, + Character: 1, + }, + End: snyk.Position{ + Line: 1, + Character: 2, + }, + }, + Message: "ossMessage", + FormattedMessage: "ossFormattedMessage", + AffectedFilePath: "ossAffectedFilePath", + Product: product.ProductOpenSource, + References: []snyk.Reference{}, + IssueDescriptionURL: &url.URL{}, + CodeActions: []snyk.CodeAction{}, + CodelensCommands: []snyk.CommandData{}, + AdditionalData: lsp2.OssIssueData{ + License: "additionalData.License", + Identifiers: lsp2.OssIdentifiers{ + CWE: []string{"789"}, + CVE: []string{"123"}, + }, + Description: "OSS description", + Language: "additionalData.Language", + PackageManager: "additionalData.PackageManager", + PackageName: "additionalData.PackageName", + Name: "additionalData.Name", + Version: "additionalData.Version", + Exploit: "additionalData.Exploit", + CVSSv3: "additionalData.CVSSv3", + CvssScore: "1.1", + FixedIn: []string{"1.1.1"}, + From: []string{"1.1.1"}, + UpgradePath: []string{"1.1.1"}, + IsPatchable: true, + IsUpgradable: true, + ProjectName: "additionalData.ProjectName", + DisplayTargetFile: "additionalData.DisplayTargetFile", + }, + }, + } + + // Act - run the test + scanNotifier.SendSuccess(product.ProductOpenSource, folderPath, issues) + + // Assert - check the messages matches the expected message for each product + for _, msg := range mockNotifier.SentMessages() { + actualUIOssIssue := msg.(lsp2.SnykScanParams).Issues + assert.Equal(t, expectedUIScanIssue, actualUIOssIssue) + return + } +} + func Test_SendSuccess_SendsForSnykCode(t *testing.T) { testutil.UnitTest(t) From 0929d5eaf26a2109e4392f49425e53c34d65f9c6 Mon Sep 17 00:00:00 2001 From: Jason Luong Date: Wed, 18 Oct 2023 12:00:49 +0100 Subject: [PATCH 3/9] fix: unit test empty result --- .../server/notification/scan_notifier.go | 15 ++++ .../server/notification/scan_notifier_test.go | 79 +++++++++++-------- domain/snyk/issues.go | 23 ++++++ infrastructure/oss/issue.go | 58 ++++++++++++++ 4 files changed, 141 insertions(+), 34 deletions(-) diff --git a/application/server/notification/scan_notifier.go b/application/server/notification/scan_notifier.go index 3ca3c9909..d4df7f49a 100644 --- a/application/server/notification/scan_notifier.go +++ b/application/server/notification/scan_notifier.go @@ -12,6 +12,7 @@ import ( var enabledProducts = map[product.Product]bool{ product.ProductCode: true, product.ProductInfrastructureAsCode: true, + product.ProductOpenSource: true, } type scanNotifier struct { @@ -89,6 +90,20 @@ func (n *scanNotifier) sendSuccess(pr product.Product, folderPath string, issues ) } +// TODO: implement appendOssIssues +// func (n *scanNotifier) appendOssIssues(scanIssues []lsp.ScanIssue, folderPath string, issues []snyk.Issue) []lsp.ScanIssue { +// for _, issue := range issues { +// additionalData, ok := issue.AdditionalData.(snyk.OssIssueData) +// if !ok { +// continue // skip non-oss issues +// } + +// scanIssues = append(scanIssues, lsp.ScanIssue{}) +// } + +// return scanIssues +// } + func (n *scanNotifier) appendIacIssues(scanIssues []lsp.ScanIssue, folderPath string, issues []snyk.Issue) []lsp.ScanIssue { for _, issue := range issues { additionalData, ok := issue.AdditionalData.(snyk.IaCIssueData) diff --git a/application/server/notification/scan_notifier_test.go b/application/server/notification/scan_notifier_test.go index 76047339e..d40c4ab7f 100644 --- a/application/server/notification/scan_notifier_test.go +++ b/application/server/notification/scan_notifier_test.go @@ -223,34 +223,34 @@ func Test_SendSuccess_SendsForOpenSource(t *testing.T) { Severity: "critical", FilePath: "ossAffectedFilePath", AdditionalData: lsp2.OssIssueData{ - License: "additionalData.License", + License: "OSS License", Identifiers: lsp2.OssIdentifiers{ CWE: []string{"789"}, CVE: []string{"123"}, }, Description: "OSS description", - Language: "additionalData.Language", - PackageManager: "additionalData.PackageManager", - PackageName: "additionalData.PackageName", - Name: "additionalData.Name", - Version: "additionalData.Version", - Exploit: "additionalData.Exploit", - CVSSv3: "additionalData.CVSSv3", + Language: "OSS Language", + PackageManager: "OSS PackageManager", + PackageName: "OSS PackageName", + Name: "OSS Name", + Version: "OSS Version", + Exploit: "OSS Exploit", + CVSSv3: "OSS CVSSv3", CvssScore: "1.1", FixedIn: []string{"1.1.1"}, From: []string{"1.1.1"}, UpgradePath: []string{"1.1.1"}, IsPatchable: true, IsUpgradable: true, - ProjectName: "additionalData.ProjectName", - DisplayTargetFile: "additionalData.DisplayTargetFile", + ProjectName: "OSS ProjectName", + DisplayTargetFile: "OSS DisplayTargetFile", }, }, } issues := []snyk.Issue{ { // OSS issue - ID: "ossID", + ID: "SNYK-JS-BABELTRAVERSE-5962463", Severity: snyk.Critical, IssueType: 1, Range: snyk.Range{ @@ -263,36 +263,44 @@ func Test_SendSuccess_SendsForOpenSource(t *testing.T) { Character: 2, }, }, - Message: "ossMessage", - FormattedMessage: "ossFormattedMessage", + Message: "Incomplete List of Disallowed Inputs", + FormattedMessage: "Incomplete List of Disallowed Inputs", AffectedFilePath: "ossAffectedFilePath", Product: product.ProductOpenSource, References: []snyk.Reference{}, IssueDescriptionURL: &url.URL{}, CodeActions: []snyk.CodeAction{}, CodelensCommands: []snyk.CommandData{}, - AdditionalData: lsp2.OssIssueData{ - License: "additionalData.License", - Identifiers: lsp2.OssIdentifiers{ - CWE: []string{"789"}, - CVE: []string{"123"}, + Ecosystem: "OSS Ecosystem", + CWEs: []string{"CWE-184"}, + CVEs: []string{"CVE-2023-45133"}, + AdditionalData: snyk.OssIssueData{ + Key: "OSS Key", + Name: "OSS Name", + LineNumber: 1, + Description: "OSS description", + References: []snyk.Reference{}, + Version: "OSS Version", + License: "OSS License", + PackageManager: "OSS PackageManager", + PackageName: "OSS PackageName", + From: []string{"babel/transverse@6.26.0"}, + GHSA: []string{"GHSA-123"}, + FixedIn: []string{}, + UpgradePath: []any{ + "@angular/cli@1.0.0", + "istanbul-instrumenter-loader@2.0.0", + "istanbul-lib-instrument@1.10.2", + "babel-template@6.26.0", + "babel-traverse@6.26.0", }, - Description: "OSS description", - Language: "additionalData.Language", - PackageManager: "additionalData.PackageManager", - PackageName: "additionalData.PackageName", - Name: "additionalData.Name", - Version: "additionalData.Version", - Exploit: "additionalData.Exploit", - CVSSv3: "additionalData.CVSSv3", - CvssScore: "1.1", - FixedIn: []string{"1.1.1"}, - From: []string{"1.1.1"}, - UpgradePath: []string{"1.1.1"}, - IsPatchable: true, - IsUpgradable: true, - ProjectName: "additionalData.ProjectName", - DisplayTargetFile: "additionalData.DisplayTargetFile", + IsUpgradable: false, + CVSSv3: "OSS CVSSv3", + CvssScore: 9.9, + Exploit: "OSS Exploit", + IsPatchable: false, + ProjectName: "OSS ProjectName", + DisplayTargetFile: "OSS DisplayTargetFile", }, }, } @@ -300,6 +308,9 @@ func Test_SendSuccess_SendsForOpenSource(t *testing.T) { // Act - run the test scanNotifier.SendSuccess(product.ProductOpenSource, folderPath, issues) + // Assert - check that there are messages sent + assert.NotEmpty(t, mockNotifier.SentMessages()) + // Assert - check the messages matches the expected message for each product for _, msg := range mockNotifier.SentMessages() { actualUIOssIssue := msg.(lsp2.SnykScanParams).Issues diff --git a/domain/snyk/issues.go b/domain/snyk/issues.go index 1343a4fbe..db491e66d 100644 --- a/domain/snyk/issues.go +++ b/domain/snyk/issues.go @@ -106,6 +106,29 @@ type MarkerPosition struct { File string `json:"file"` } +type OssIssueData struct { + Key string `json:"key"` + Name string `json:"name"` + LineNumber int `json:"lineNumber"` + Description string `json:"description"` + References []Reference `json:"references,omitempty"` + Version string `json:"version"` + License string `json:"license,omitempty"` + PackageManager string `json:"packageManager"` + PackageName string `json:"packageName"` + From []string `json:"from"` + GHSA []string `json:"GHSA,omitempty"` + FixedIn []string `json:"fixedIn,omitempty"` + UpgradePath []any `json:"upgradePath,omitempty"` + IsUpgradable bool `json:"isUpgradable,omitempty"` + CVSSv3 string `json:"CVSSv3,omitempty"` + CvssScore float64 `json:"cvssScore,omitempty"` + Exploit string `json:"exploit,omitempty"` + IsPatchable bool `json:"isPatchable"` + ProjectName string `json:"projectName"` + DisplayTargetFile string `json:"displayTargetFile"` +} + type IaCIssueData struct { // Unique key identifying an issue in the whole result set Key string `json:"key"` diff --git a/infrastructure/oss/issue.go b/infrastructure/oss/issue.go index b6a01c024..7dda1c465 100644 --- a/infrastructure/oss/issue.go +++ b/infrastructure/oss/issue.go @@ -17,8 +17,11 @@ package oss import ( + "crypto/sha256" + "encoding/hex" "fmt" "net/url" + "strconv" "strings" "github.com/gomarkdown/markdown" @@ -204,6 +207,56 @@ func toIssue( Ecosystem: issue.PackageManager, CWEs: issue.Identifiers.CWE, CVEs: issue.Identifiers.CVE, + AdditionalData: issue.toAdditionalData(affectedFilePath), + } +} + +func (o ossIssue) toAdditionalData(filepath string) snyk.OssIssueData { + var additionalData snyk.OssIssueData + additionalData.Key = getIssueKey(filepath, o) + additionalData.Name = o.Name + additionalData.LineNumber = o.LineNumber + additionalData.Description = o.Description + additionalData.References = o.toReferences() + additionalData.Version = o.Version + /** TODO: IDE (lsp.ScanIssue) requires the following fields from scanresult: + - License + - CVSSv3 + - CvssScore + - Exploit + - IsPatchable + - ProjectName + - DisplayTargetFile + so we need to update convertScanResultToIssues to get these fields + **/ + // additionalData.License = ??? + additionalData.PackageManager = o.PackageManager + additionalData.PackageName = o.PackageName + additionalData.From = o.From + additionalData.GHSA = o.Identifiers.GHSA + additionalData.FixedIn = o.FixedIn + additionalData.UpgradePath = o.UpgradePath + additionalData.IsUpgradable = o.IsUpgradable + + return additionalData +} + +func (o ossIssue) toReferences() []snyk.Reference { + var references []snyk.Reference + for _, ref := range o.References { + references = append(references, ref.toReference()) + } + return references +} + +func (r reference) toReference() snyk.Reference { + url, err := url.Parse(string(r.Url)) + if err != nil { + log.Err(err).Msg("Unable to parse reference url: " + string(r.Url)) + } + return snyk.Reference{ + Url: url, + Title: r.Title, } } @@ -233,3 +286,8 @@ func convertScanResultToIssues( } return issues } + +func getIssueKey(affectedFilePath string, issue ossIssue) string { + id := sha256.Sum256([]byte(affectedFilePath + strconv.Itoa(issue.LineNumber) + issue.Id)) + return hex.EncodeToString(id[:16]) +} From c74ffeb4086230e75393fe019dc4a82a849d7d3f Mon Sep 17 00:00:00 2001 From: Jason Luong Date: Thu, 19 Oct 2023 12:42:02 +0100 Subject: [PATCH 4/9] chore: update ossIssue with additional fields needed for oss scan issues --- infrastructure/oss/types.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/infrastructure/oss/types.go b/infrastructure/oss/types.go index 109b2a2c2..97ed598a6 100644 --- a/infrastructure/oss/types.go +++ b/infrastructure/oss/types.go @@ -49,6 +49,11 @@ type ossIssue struct { FixedIn []string `json:"fixedIn,omitempty"` UpgradePath []any `json:"upgradePath,omitempty"` IsUpgradable bool `json:"isUpgradable,omitempty"` + CVSSv3 string `json:"CVSSv3,omitempty"` + CvssScore float64 `json:"cvssScore,omitempty"` + Exploit string `json:"exploit,omitempty"` + IsPatchable bool `json:"isPatchable"` + License string `json:"license,omitempty"` } type licensesPolicy struct { From 8e5c59296f56da56b7fcd63f878745bd2951aed6 Mon Sep 17 00:00:00 2001 From: Jason Luong Date: Thu, 19 Oct 2023 12:42:55 +0100 Subject: [PATCH 5/9] chore: update snyk.Issue struct to include additional common fields --- domain/snyk/issues.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/domain/snyk/issues.go b/domain/snyk/issues.go index db491e66d..a96ed052f 100644 --- a/domain/snyk/issues.go +++ b/domain/snyk/issues.go @@ -60,6 +60,10 @@ type Issue struct { CWEs []string // A slice of the CVEs of the issue CVEs []string + // Name of project + ProjectName string + // target manifest file + DisplayTargetFile string // AdditionalData contains data that can be passed by the product (e.g. for presentation) AdditionalData any } From 8b058c0b62974cd8eadb16b53e2b160da9a3dcd0 Mon Sep 17 00:00:00 2001 From: Jason Luong Date: Thu, 19 Oct 2023 12:43:35 +0100 Subject: [PATCH 6/9] feat: add oss additional data when creating oss issues --- infrastructure/oss/issue.go | 21 +++++++++------------ infrastructure/oss/oss_test.go | 2 +- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/infrastructure/oss/issue.go b/infrastructure/oss/issue.go index 7dda1c465..3289d7614 100644 --- a/infrastructure/oss/issue.go +++ b/infrastructure/oss/issue.go @@ -165,6 +165,7 @@ func (i *ossIssue) ToIssueSeverity() snyk.Severity { func toIssue( affectedFilePath string, issue ossIssue, + scanResult *scanResult, issueRange snyk.Range, learnService learn.Service, ep error_reporting.ErrorReporter, @@ -207,6 +208,8 @@ func toIssue( Ecosystem: issue.PackageManager, CWEs: issue.Identifiers.CWE, CVEs: issue.Identifiers.CVE, + ProjectName: scanResult.ProjectName, + DisplayTargetFile: scanResult.DisplayTargetFile, AdditionalData: issue.toAdditionalData(affectedFilePath), } } @@ -219,17 +222,7 @@ func (o ossIssue) toAdditionalData(filepath string) snyk.OssIssueData { additionalData.Description = o.Description additionalData.References = o.toReferences() additionalData.Version = o.Version - /** TODO: IDE (lsp.ScanIssue) requires the following fields from scanresult: - - License - - CVSSv3 - - CvssScore - - Exploit - - IsPatchable - - ProjectName - - DisplayTargetFile - so we need to update convertScanResultToIssues to get these fields - **/ - // additionalData.License = ??? + additionalData.License = o.License additionalData.PackageManager = o.PackageManager additionalData.PackageName = o.PackageName additionalData.From = o.From @@ -237,6 +230,10 @@ func (o ossIssue) toAdditionalData(filepath string) snyk.OssIssueData { additionalData.FixedIn = o.FixedIn additionalData.UpgradePath = o.UpgradePath additionalData.IsUpgradable = o.IsUpgradable + additionalData.CVSSv3 = o.CVSSv3 + additionalData.CvssScore = o.CvssScore + additionalData.Exploit = o.Exploit + additionalData.IsPatchable = o.IsPatchable return additionalData } @@ -279,7 +276,7 @@ func convertScanResultToIssues( continue } issueRange := findRange(issue, path, fileContent) - snykIssue := toIssue(path, issue, issueRange, ls, ep) + snykIssue := toIssue(path, issue, res, issueRange, ls, ep) packageIssueCache[packageKey] = append(packageIssueCache[packageKey], snykIssue) issues = append(issues, snykIssue) duplicateCheckMap[duplicateKey] = true diff --git a/infrastructure/oss/oss_test.go b/infrastructure/oss/oss_test.go index 46f1bb334..4ed5ab68c 100644 --- a/infrastructure/oss/oss_test.go +++ b/infrastructure/oss/oss_test.go @@ -132,7 +132,7 @@ func Test_toIssue_LearnParameterConversion(t *testing.T) { learnService: getLearnMock(t), } - issue := toIssue("testPath", ossIssue, snyk.Range{}, scanner.learnService, scanner.errorReporter) + issue := toIssue("testPath", ossIssue, &scanResult{}, snyk.Range{}, scanner.learnService, scanner.errorReporter) assert.Equal(t, ossIssue.Id, issue.ID) assert.Equal(t, ossIssue.Identifiers.CWE, issue.CWEs) From 729be3c0ce7b6c5d2f8ad25c75861366c0f97fd9 Mon Sep 17 00:00:00 2001 From: Jason Luong Date: Thu, 19 Oct 2023 13:39:56 +0100 Subject: [PATCH 7/9] feat: implementating oss snyk/scan notifer --- .../server/notification/scan_notifier.go | 52 +++++++++++++++---- .../server/notification/scan_notifier_test.go | 48 +++++++++-------- domain/snyk/issues.go | 6 +-- infrastructure/oss/issue.go | 10 ++-- infrastructure/oss/types.go | 1 + internal/lsp/message_types.go | 2 +- 6 files changed, 76 insertions(+), 43 deletions(-) diff --git a/application/server/notification/scan_notifier.go b/application/server/notification/scan_notifier.go index d4df7f49a..9d2a84742 100644 --- a/application/server/notification/scan_notifier.go +++ b/application/server/notification/scan_notifier.go @@ -2,6 +2,7 @@ package notification import ( "errors" + "strconv" "github.com/snyk/snyk-ls/domain/ide/notification" "github.com/snyk/snyk-ls/domain/snyk" @@ -78,6 +79,8 @@ func (n *scanNotifier) sendSuccess(pr product.Product, folderPath string, issues scanIssues = n.appendIacIssues(scanIssues, folderPath, issues) } else if pr == product.ProductCode { scanIssues = n.appendCodeIssues(scanIssues, folderPath, issues) + } else if pr == product.ProductOpenSource { + scanIssues = n.appendOssIssues(scanIssues, folderPath, issues) } n.notifier.Send( @@ -90,19 +93,46 @@ func (n *scanNotifier) sendSuccess(pr product.Product, folderPath string, issues ) } -// TODO: implement appendOssIssues -// func (n *scanNotifier) appendOssIssues(scanIssues []lsp.ScanIssue, folderPath string, issues []snyk.Issue) []lsp.ScanIssue { -// for _, issue := range issues { -// additionalData, ok := issue.AdditionalData.(snyk.OssIssueData) -// if !ok { -// continue // skip non-oss issues -// } +func (n *scanNotifier) appendOssIssues(scanIssues []lsp.ScanIssue, folderPath string, issues []snyk.Issue) []lsp.ScanIssue { + for _, issue := range issues { + additionalData, ok := issue.AdditionalData.(snyk.OssIssueData) + if !ok { + continue // skip non-oss issues + } -// scanIssues = append(scanIssues, lsp.ScanIssue{}) -// } + scanIssues = append(scanIssues, lsp.ScanIssue{ + Id: additionalData.Key, + Title: additionalData.Title, + Severity: issue.Severity.String(), + FilePath: issue.AffectedFilePath, + AdditionalData: lsp.OssIssueData{ + License: additionalData.License, + Identifiers: lsp.OssIdentifiers{ + CWE: issue.CWEs, + CVE: issue.CVEs, + }, + Description: additionalData.Description, + Language: additionalData.Language, + PackageManager: additionalData.PackageManager, + PackageName: additionalData.PackageName, + Name: additionalData.Name, + Version: additionalData.Version, + Exploit: additionalData.Exploit, + CVSSv3: additionalData.CVSSv3, + CvssScore: strconv.FormatFloat(additionalData.CvssScore, 'f', 2, 64), // convert float64 to string with 2 decimal places + FixedIn: additionalData.FixedIn, + From: additionalData.From, + UpgradePath: additionalData.UpgradePath, + IsPatchable: additionalData.IsPatchable, + IsUpgradable: additionalData.IsUpgradable, + ProjectName: additionalData.ProjectName, + DisplayTargetFile: additionalData.DisplayTargetFile, + }, + }) + } -// return scanIssues -// } + return scanIssues +} func (n *scanNotifier) appendIacIssues(scanIssues []lsp.ScanIssue, folderPath string, issues []snyk.Issue) []lsp.ScanIssue { for _, issue := range issues { diff --git a/application/server/notification/scan_notifier_test.go b/application/server/notification/scan_notifier_test.go index d40c4ab7f..14c3a72a9 100644 --- a/application/server/notification/scan_notifier_test.go +++ b/application/server/notification/scan_notifier_test.go @@ -218,30 +218,33 @@ func Test_SendSuccess_SendsForOpenSource(t *testing.T) { expectedUIScanIssue := []lsp2.ScanIssue{ { - Id: "ossID", - Title: "ossTitle", + Id: "OSS Key", + Title: "OSS Title", Severity: "critical", FilePath: "ossAffectedFilePath", AdditionalData: lsp2.OssIssueData{ License: "OSS License", Identifiers: lsp2.OssIdentifiers{ - CWE: []string{"789"}, - CVE: []string{"123"}, + CWE: []string{"CWE-184"}, + CVE: []string{"CVE-2023-45133"}, }, - Description: "OSS description", - Language: "OSS Language", - PackageManager: "OSS PackageManager", - PackageName: "OSS PackageName", - Name: "OSS Name", - Version: "OSS Version", - Exploit: "OSS Exploit", - CVSSv3: "OSS CVSSv3", - CvssScore: "1.1", - FixedIn: []string{"1.1.1"}, - From: []string{"1.1.1"}, - UpgradePath: []string{"1.1.1"}, - IsPatchable: true, - IsUpgradable: true, + Description: "OSS Description", + Language: "js", + PackageManager: "OSS PackageManager", + PackageName: "OSS PackageName", + Name: "OSS Name", + Version: "OSS Version", + Exploit: "OSS Exploit", + CVSSv3: "OSS CVSSv3", + CvssScore: "9.90", + FixedIn: []string{}, + From: []string{"babel/transverse@6.26.0"}, + UpgradePath: []any{ + true, + "babel-traverse@6.26.0", + }, + IsPatchable: false, + IsUpgradable: false, ProjectName: "OSS ProjectName", DisplayTargetFile: "OSS DisplayTargetFile", }, @@ -276,9 +279,10 @@ func Test_SendSuccess_SendsForOpenSource(t *testing.T) { CVEs: []string{"CVE-2023-45133"}, AdditionalData: snyk.OssIssueData{ Key: "OSS Key", + Title: "OSS Title", Name: "OSS Name", LineNumber: 1, - Description: "OSS description", + Description: "OSS Description", References: []snyk.Reference{}, Version: "OSS Version", License: "OSS License", @@ -288,10 +292,7 @@ func Test_SendSuccess_SendsForOpenSource(t *testing.T) { GHSA: []string{"GHSA-123"}, FixedIn: []string{}, UpgradePath: []any{ - "@angular/cli@1.0.0", - "istanbul-instrumenter-loader@2.0.0", - "istanbul-lib-instrument@1.10.2", - "babel-template@6.26.0", + true, "babel-traverse@6.26.0", }, IsUpgradable: false, @@ -301,6 +302,7 @@ func Test_SendSuccess_SendsForOpenSource(t *testing.T) { IsPatchable: false, ProjectName: "OSS ProjectName", DisplayTargetFile: "OSS DisplayTargetFile", + Language: "js", }, }, } diff --git a/domain/snyk/issues.go b/domain/snyk/issues.go index a96ed052f..c6eb4f3fe 100644 --- a/domain/snyk/issues.go +++ b/domain/snyk/issues.go @@ -60,10 +60,6 @@ type Issue struct { CWEs []string // A slice of the CVEs of the issue CVEs []string - // Name of project - ProjectName string - // target manifest file - DisplayTargetFile string // AdditionalData contains data that can be passed by the product (e.g. for presentation) AdditionalData any } @@ -112,6 +108,7 @@ type MarkerPosition struct { type OssIssueData struct { Key string `json:"key"` + Title string `json:"title"` Name string `json:"name"` LineNumber int `json:"lineNumber"` Description string `json:"description"` @@ -131,6 +128,7 @@ type OssIssueData struct { IsPatchable bool `json:"isPatchable"` ProjectName string `json:"projectName"` DisplayTargetFile string `json:"displayTargetFile"` + Language string `json:"language"` } type IaCIssueData struct { diff --git a/infrastructure/oss/issue.go b/infrastructure/oss/issue.go index 3289d7614..81991071f 100644 --- a/infrastructure/oss/issue.go +++ b/infrastructure/oss/issue.go @@ -208,15 +208,14 @@ func toIssue( Ecosystem: issue.PackageManager, CWEs: issue.Identifiers.CWE, CVEs: issue.Identifiers.CVE, - ProjectName: scanResult.ProjectName, - DisplayTargetFile: scanResult.DisplayTargetFile, - AdditionalData: issue.toAdditionalData(affectedFilePath), + AdditionalData: issue.toAdditionalData(affectedFilePath, scanResult), } } -func (o ossIssue) toAdditionalData(filepath string) snyk.OssIssueData { +func (o ossIssue) toAdditionalData(filepath string, scanResult *scanResult) snyk.OssIssueData { var additionalData snyk.OssIssueData additionalData.Key = getIssueKey(filepath, o) + additionalData.Title = o.Title additionalData.Name = o.Name additionalData.LineNumber = o.LineNumber additionalData.Description = o.Description @@ -234,6 +233,9 @@ func (o ossIssue) toAdditionalData(filepath string) snyk.OssIssueData { additionalData.CvssScore = o.CvssScore additionalData.Exploit = o.Exploit additionalData.IsPatchable = o.IsPatchable + additionalData.ProjectName = scanResult.ProjectName + additionalData.DisplayTargetFile = scanResult.DisplayTargetFile + additionalData.Language = o.Language return additionalData } diff --git a/infrastructure/oss/types.go b/infrastructure/oss/types.go index 97ed598a6..379e4aca8 100644 --- a/infrastructure/oss/types.go +++ b/infrastructure/oss/types.go @@ -54,6 +54,7 @@ type ossIssue struct { Exploit string `json:"exploit,omitempty"` IsPatchable bool `json:"isPatchable"` License string `json:"license,omitempty"` + Language string `json:"language,omitempty"` } type licensesPolicy struct { diff --git a/internal/lsp/message_types.go b/internal/lsp/message_types.go index b83eef582..18135994e 100644 --- a/internal/lsp/message_types.go +++ b/internal/lsp/message_types.go @@ -1047,7 +1047,7 @@ type OssIssueData struct { CvssScore string `json:"cvssScore,omitempty"` FixedIn []string `json:"fixedIn,omitempty"` From []string `json:"from"` - UpgradePath []string `json:"upgradePath"` + UpgradePath []any `json:"upgradePath"` IsPatchable bool `json:"isPatchable"` IsUpgradable bool `json:"isUpgradable"` ProjectName string `json:"projectName"` From 54910a21fab6c54564306ed266926b4962f40f95 Mon Sep 17 00:00:00 2001 From: Jason Luong Date: Thu, 19 Oct 2023 13:50:38 +0100 Subject: [PATCH 8/9] fix: failing test --- application/server/notification/scan_notifier_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/server/notification/scan_notifier_test.go b/application/server/notification/scan_notifier_test.go index 14c3a72a9..2dcb07ef9 100644 --- a/application/server/notification/scan_notifier_test.go +++ b/application/server/notification/scan_notifier_test.go @@ -493,7 +493,7 @@ func Test_SendInProgress_SendsForAllEnabledProducts(t *testing.T) { scanNotifier.SendInProgress("/test/folderPath") // Assert - assert.Equal(t, 2, len(mockNotifier.SentMessages())) + assert.Equal(t, 3, len(mockNotifier.SentMessages())) } func containsMatchingMessage(t *testing.T, From 961531c4eb918e7cbbe0bec091f5bb777443e62e Mon Sep 17 00:00:00 2001 From: Jason Luong Date: Thu, 19 Oct 2023 13:53:03 +0100 Subject: [PATCH 9/9] chore: remove unused ghsa field in snyk.OssIssueData --- application/server/notification/scan_notifier_test.go | 1 - domain/snyk/issues.go | 1 - infrastructure/oss/issue.go | 1 - 3 files changed, 3 deletions(-) diff --git a/application/server/notification/scan_notifier_test.go b/application/server/notification/scan_notifier_test.go index 2dcb07ef9..7e6300e60 100644 --- a/application/server/notification/scan_notifier_test.go +++ b/application/server/notification/scan_notifier_test.go @@ -289,7 +289,6 @@ func Test_SendSuccess_SendsForOpenSource(t *testing.T) { PackageManager: "OSS PackageManager", PackageName: "OSS PackageName", From: []string{"babel/transverse@6.26.0"}, - GHSA: []string{"GHSA-123"}, FixedIn: []string{}, UpgradePath: []any{ true, diff --git a/domain/snyk/issues.go b/domain/snyk/issues.go index c6eb4f3fe..b46258bfa 100644 --- a/domain/snyk/issues.go +++ b/domain/snyk/issues.go @@ -118,7 +118,6 @@ type OssIssueData struct { PackageManager string `json:"packageManager"` PackageName string `json:"packageName"` From []string `json:"from"` - GHSA []string `json:"GHSA,omitempty"` FixedIn []string `json:"fixedIn,omitempty"` UpgradePath []any `json:"upgradePath,omitempty"` IsUpgradable bool `json:"isUpgradable,omitempty"` diff --git a/infrastructure/oss/issue.go b/infrastructure/oss/issue.go index 81991071f..14c06e4fa 100644 --- a/infrastructure/oss/issue.go +++ b/infrastructure/oss/issue.go @@ -225,7 +225,6 @@ func (o ossIssue) toAdditionalData(filepath string, scanResult *scanResult) snyk additionalData.PackageManager = o.PackageManager additionalData.PackageName = o.PackageName additionalData.From = o.From - additionalData.GHSA = o.Identifiers.GHSA additionalData.FixedIn = o.FixedIn additionalData.UpgradePath = o.UpgradePath additionalData.IsUpgradable = o.IsUpgradable