From a8fc0edd5b1632c2c90219569ef5e015dbdad1f0 Mon Sep 17 00:00:00 2001 From: Guilherme Macedo Date: Tue, 25 Jun 2024 10:47:51 -0300 Subject: [PATCH] internal/openvex: add initial support for identifying affected product Signed-off-by: Guilherme Macedo --- internal/openvex/handler.go | 5 ++++- internal/openvex/vex.go | 3 --- internal/osv/osv.go | 12 ++++++++++++ internal/semver/semver.go | 4 ++-- internal/vulncheck/emit.go | 8 ++++++++ 5 files changed, 26 insertions(+), 6 deletions(-) diff --git a/internal/openvex/handler.go b/internal/openvex/handler.go index 5087eb7a..8d712b73 100644 --- a/internal/openvex/handler.go +++ b/internal/openvex/handler.go @@ -14,6 +14,7 @@ import ( "golang.org/x/vuln/internal/govulncheck" "golang.org/x/vuln/internal/osv" + "golang.org/x/vuln/internal/semver" ) type findingLevel int @@ -131,7 +132,9 @@ func statements(h *handler) []Statement { }, Products: []Product{ { - ID: DefaultPID, + ID: fmt.Sprintf("pkg:golang/%s@%s", + osv.Internal.AffectedPath, + semver.RemoveSemverPrefix(osv.Internal.AffectedVersion)), }, }, } diff --git a/internal/openvex/vex.go b/internal/openvex/vex.go index e60ce750..8d9f0c5c 100644 --- a/internal/openvex/vex.go +++ b/internal/openvex/vex.go @@ -20,7 +20,6 @@ const ( Impact = "Govulncheck determined that the vulnerable code isn't called" DefaultAuthor = "Unknown Author" - DefaultPID = "Unknown Product" // The following are defined by the VEX standard. StatusAffected = "affected" @@ -102,7 +101,5 @@ type Vulnerability struct { // Product identifies the products associated with the given vuln. type Product struct { - // For now, the ID will always be "Unknown product". - // This is temporary and is subject to change. ID string `json:"@id,omitempty"` } diff --git a/internal/osv/osv.go b/internal/osv/osv.go index 0bb44b27..bb97cf05 100644 --- a/internal/osv/osv.go +++ b/internal/osv/osv.go @@ -215,6 +215,9 @@ type Entry struct { // DatabaseSpecific contains additional information about the // vulnerability, specific to the Go vulnerability database. DatabaseSpecific *DatabaseSpecific `json:"database_specific,omitempty"` + // Internal contains information internal only to govulncheck that is + // not present in the OSV specification. + Internal Internal } // Credit represents a credit for the discovery, confirmation, patch, or @@ -238,3 +241,12 @@ type DatabaseSpecific struct { // The review status of this report (UNREVIEWED or REVIEWED). ReviewStatus ReviewStatus `json:"review_status,omitempty"` } + +// Internal contains information internal and specific only to govulncheck that +// is not present in the OSV specification. +type Internal struct { + // The affected path (package import) for the OpenVEX products field. + AffectedPath string + // The affected version for the OpenVEX products field. + AffectedVersion string +} diff --git a/internal/semver/semver.go b/internal/semver/semver.go index fe0f701b..9517140b 100644 --- a/internal/semver/semver.go +++ b/internal/semver/semver.go @@ -25,7 +25,7 @@ func addSemverPrefix(s string) string { // removeSemverPrefix removes the 'v' or 'go' prefixes from go-style // SEMVER strings, for usage in the public vulnerability format. -func removeSemverPrefix(s string) string { +func RemoveSemverPrefix(s string) string { s = strings.TrimPrefix(s, "v") s = strings.TrimPrefix(s, "go") return s @@ -36,7 +36,7 @@ func removeSemverPrefix(s string) string { // Input may be a bare SEMVER ("1.2.3"), Go prefixed SEMVER ("go1.2.3"), // or already canonical SEMVER ("v1.2.3"). func canonicalizeSemverPrefix(s string) string { - return addSemverPrefix(removeSemverPrefix(s)) + return addSemverPrefix(RemoveSemverPrefix(s)) } // Less returns whether v1 < v2, where v1 and v2 are diff --git a/internal/vulncheck/emit.go b/internal/vulncheck/emit.go index fc9b2d7a..b0d7699e 100644 --- a/internal/vulncheck/emit.go +++ b/internal/vulncheck/emit.go @@ -18,6 +18,14 @@ import ( func emitOSVs(handler govulncheck.Handler, modVulns []*ModVulns) error { for _, mv := range modVulns { for _, v := range mv.Vulns { + // Retrieve the affected path (package) and version for + // the OpenVEX document. + v.Internal.AffectedPath = mv.Module.Path + v.Internal.AffectedVersion = mv.Module.Version + if mv.Module.Replace != nil { + v.Internal.AffectedPath = mv.Module.Replace.Path + v.Internal.AffectedVersion = mv.Module.Replace.Version + } if err := handler.OSV(v); err != nil { return err }