Skip to content

Commit

Permalink
fix(report): tidy dependencies for multiple repo on integration with …
Browse files Browse the repository at this point in the history
…GSA (#1593)

* initialize dependencyGraphManifests out of loop

* remove GitHubSecurityAlert.PackageName

* tidy dependency map for multi repo

* set repo name into SBOM components & purl for multi repo
  • Loading branch information
kl-sinclair authored Feb 7, 2023
1 parent ad2edbb commit 1927ed3
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 17 deletions.
2 changes: 2 additions & 0 deletions detector/detector.go
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,8 @@ func DetectGitHubCves(r *models.ScanResult, githubConfs map[string]config.GitHub
if len(githubConfs) == 0 {
return nil
}

r.GitHubManifests = models.DependencyGraphManifests{}
for ownerRepo, setting := range githubConfs {
ss := strings.Split(ownerRepo, "/")
if len(ss) != 2 {
Expand Down
12 changes: 4 additions & 8 deletions detector/github.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,8 @@ func DetectGitHubSecurityAlerts(r *models.ScanResult, owner, repo, token string,
continue
}

repoURLPkgName := fmt.Sprintf("%s %s",
alerts.Data.Repository.URL, v.Node.SecurityVulnerability.Package.Name)

m := models.GitHubSecurityAlert{
PackageName: repoURLPkgName,
Repository: alerts.Data.Repository.URL,
Repository: alerts.Data.Repository.URL,
Package: models.GSAVulnerablePackage{
Name: v.Node.SecurityVulnerability.Package.Name,
Ecosystem: v.Node.SecurityVulnerability.Package.Ecosystem,
Expand Down Expand Up @@ -219,7 +215,6 @@ func DetectGitHubDependencyGraph(r *models.ScanResult, owner, repo, token string
)
//TODO Proxy
httpClient := oauth2.NewClient(context.Background(), src)
r.GitHubManifests = models.DependencyGraphManifests{}

return fetchDependencyGraph(r, httpClient, owner, repo, "", "")
}
Expand Down Expand Up @@ -268,9 +263,10 @@ func fetchDependencyGraph(r *models.ScanResult, httpClient *http.Client, owner,

dependenciesAfter = ""
for _, m := range graph.Data.Repository.DependencyGraphManifests.Edges {
manifest, ok := r.GitHubManifests[m.Node.Filename]
manifest, ok := r.GitHubManifests[m.Node.BlobPath]
if !ok {
manifest = models.DependencyGraphManifest{
BlobPath: m.Node.BlobPath,
Filename: m.Node.Filename,
Repository: m.Node.Repository.URL,
Dependencies: []models.Dependency{},
Expand All @@ -284,7 +280,7 @@ func fetchDependencyGraph(r *models.ScanResult, httpClient *http.Client, owner,
Requirements: d.Node.Requirements,
})
}
r.GitHubManifests[m.Node.Filename] = manifest
r.GitHubManifests[m.Node.BlobPath] = manifest

if m.Node.Dependencies.PageInfo.HasNextPage {
dependenciesAfter = fmt.Sprintf(`(after: \"%s\")`, m.Node.Dependencies.PageInfo.EndCursor)
Expand Down
9 changes: 8 additions & 1 deletion models/github.go
Original file line number Diff line number Diff line change
@@ -1,21 +1,28 @@
package models

import (
"fmt"
"strings"

ftypes "github.com/aquasecurity/trivy/pkg/fanal/types"
)

// DependencyGraphManifests has a map of DependencyGraphManifest
// key: Filename
// key: BlobPath
type DependencyGraphManifests map[string]DependencyGraphManifest

type DependencyGraphManifest struct {
BlobPath string `json:"blobPath"`
Filename string `json:"filename"`
Repository string `json:"repository"`
Dependencies []Dependency `json:"dependencies"`
}

// RepoURLFilename should be same format with GitHubSecurityAlert.RepoURLManifestPath()
func (m DependencyGraphManifest) RepoURLFilename() string {
return fmt.Sprintf("%s/%s", m.Repository, m.Filename)
}

// Ecosystem returns a name of ecosystem(or package manager) of manifest(lock) file in trivy way
// https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-the-dependency-graph#supported-package-ecosystems
func (m DependencyGraphManifest) Ecosystem() string {
Expand Down
9 changes: 6 additions & 3 deletions models/vulninfos.go
Original file line number Diff line number Diff line change
Expand Up @@ -299,10 +299,8 @@ func (g GitHubSecurityAlerts) Names() (names []string) {
return names
}

// GitHubSecurityAlert has detected CVE-ID, PackageName, Status fetched via GitHub API
// GitHubSecurityAlert has detected CVE-ID, GSAVulnerablePackage, Status fetched via GitHub API
type GitHubSecurityAlert struct {
// TODO: PackageName deprecated. it will be removed next time.
PackageName string `json:"packageName"`
Repository string `json:"repository"`
Package GSAVulnerablePackage `json:"package,omitempty"`
FixedIn string `json:"fixedIn"`
Expand All @@ -316,6 +314,11 @@ func (a GitHubSecurityAlert) RepoURLPackageName() string {
return fmt.Sprintf("%s %s", a.Repository, a.Package.Name)
}

// RepoURLManifestPath should be same format with DependencyGraphManifest.RepoURLFilename()
func (a GitHubSecurityAlert) RepoURLManifestPath() string {
return fmt.Sprintf("%s/%s", a.Repository, a.Package.ManifestPath)
}

type GSAVulnerablePackage struct {
Name string `json:"name"`
Ecosystem string `json:"ecosystem"`
Expand Down
10 changes: 5 additions & 5 deletions reporter/sbom/cyclonedx.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ func cdxComponents(result models.ScanResult, metaBomRef string) (*[]cdx.Componen

ghpkgToPURL := map[string]map[string]string{}
for _, ghm := range result.GitHubManifests {
ghpkgToPURL[ghm.Filename] = map[string]string{}
ghpkgToPURL[ghm.RepoURLFilename()] = map[string]string{}

ghpkgComps := ghpkgToCdxComponents(ghm, ghpkgToPURL)
bomRefs[metaBomRef] = append(bomRefs[metaBomRef], ghpkgComps[0].BOMRef)
Expand Down Expand Up @@ -275,7 +275,7 @@ func ghpkgToCdxComponents(m models.DependencyGraphManifest, ghpkgToPURL map[stri
{
BOMRef: uuid.NewString(),
Type: cdx.ComponentTypeApplication,
Name: m.Filename,
Name: m.BlobPath,
Properties: &[]cdx.Property{
{
Name: "future-architect:vuls:Type",
Expand All @@ -286,7 +286,7 @@ func ghpkgToCdxComponents(m models.DependencyGraphManifest, ghpkgToPURL map[stri
}

for _, dep := range m.Dependencies {
purl := packageurl.NewPackageURL(m.Ecosystem(), "", dep.PackageName, dep.Version(), packageurl.Qualifiers{{Key: "file_path", Value: m.Filename}}, "").ToString()
purl := packageurl.NewPackageURL(m.Ecosystem(), "", dep.PackageName, dep.Version(), packageurl.Qualifiers{{Key: "repo_url", Value: m.Repository}, {Key: "file_path", Value: m.Filename}}, "").ToString()
components = append(components, cdx.Component{
BOMRef: purl,
Type: cdx.ComponentTypeLibrary,
Expand All @@ -295,7 +295,7 @@ func ghpkgToCdxComponents(m models.DependencyGraphManifest, ghpkgToPURL map[stri
PackageURL: purl,
})

ghpkgToPURL[m.Filename][dep.PackageName] = purl
ghpkgToPURL[m.RepoURLFilename()][dep.PackageName] = purl
}

return components
Expand Down Expand Up @@ -496,7 +496,7 @@ func cdxAffects(cve models.VulnInfo, ospkgToPURL map[string]string, libpkgToPURL
}
for _, alert := range cve.GitHubSecurityAlerts {
// TODO: not in dependency graph
if purl, ok := ghpkgToPURL[alert.Package.ManifestPath][alert.Package.Name]; ok {
if purl, ok := ghpkgToPURL[alert.RepoURLManifestPath()][alert.Package.Name]; ok {
affects = append(affects, cdx.Affects{
Ref: purl,
})
Expand Down

0 comments on commit 1927ed3

Please sign in to comment.