diff --git a/controllers/vulndb_controller.go b/controllers/vulndb_controller.go index 935d59489..c2f60bf4b 100644 --- a/controllers/vulndb_controller.go +++ b/controllers/vulndb_controller.go @@ -1,7 +1,6 @@ package controllers import ( - "encoding/json" "fmt" "net/url" "strconv" @@ -216,35 +215,36 @@ type ecosystemRow struct { Count int `gorm:"count" json:"count"` } -// return the number of affected packages by ecosystem -func (c VulnDBController) GetEcosystemDistribution(ctx shared.Context) error { - results := make([]ecosystemRow, 1024) +// return the number of vulnerabilities in affected packages per ecosystem +func (c VulnDBController) GetCVEEcosystemDistribution(ctx shared.Context) error { + cveResults := make([]ecosystemRow, 0, 1024) + maliciousPackageResults := make([]ecosystemRow, 0, 64) - // static sql to get amount of packages by ecosystem - sql := `SELECT ecosystem, COUNT(*) FROM affected_components GROUP BY ecosystem;` - err := c.affectedComponentRepository.GetDB(nil).Raw(sql).Find(&results).Error + // get the amount of CVEs in affected packages per ecosystem + cveSQL := `SELECT LOWER(b.ecosystem) as ecosystem, COUNT(*) FROM cve_affected_component a + LEFT JOIN affected_components b ON b.id = a.affected_component_id + GROUP BY LOWER(b.ecosystem);` + err := c.affectedComponentRepository.GetDB(nil).Raw(cveSQL).Find(&cveResults).Error if err != nil { return echo.NewHTTPError(500, "could not fetch data from database").WithInternal(err) } - // since ecosystem have tags behind the : character we want to group them by their prefix - jsonResults := buildResultsJSON(results) - - return ctx.String(200, jsonResults) -} - -// group ecosystem by prefix ecosystem string and return the equivalent json encoding -func buildResultsJSON(rows []ecosystemRow) string { - // map to deduplicate ecosystem with different tags - aggregatedResults := make(map[string]int) + // do the same thing for malicious packages + maliciousPackagesSQL := `SELECT LOWER(b.ecosystem) as ecosystem, COUNT(*) FROM malicious_packages a + LEFT JOIN malicious_affected_components b ON a.id = b.malicious_package_id + GROUP BY LOWER(b.ecosystem);` + err = c.affectedComponentRepository.GetDB(nil).Raw(maliciousPackagesSQL).Find(&maliciousPackageResults).Error + if err != nil { + return echo.NewHTTPError(500, "could not fetch data from database").WithInternal(err) + } - // fill the map with the value of the rows - for _, row := range rows { - before, _, _ := strings.Cut(row.Ecosystem, ":") - aggregatedResults[before] += row.Count + // group the results in a map by cutting the ecosystem identifier before the ':' + ecosystemToAmount := make(map[string]int, len(cveResults)) + for _, row := range append(cveResults, maliciousPackageResults...) { + key, _, _ := strings.Cut(row.Ecosystem, ":") + ecosystemToAmount[key] += row.Count } - // marshal to JSON with proper indentation - data, _ := json.MarshalIndent(aggregatedResults, "", config.PrettyJSONIndent) - return string(data) + // convert the result in a map and return it + return ctx.JSONPretty(200, ecosystemToAmount, config.PrettyJSONIndent) } diff --git a/database/repositories/cve_repository.go b/database/repositories/cve_repository.go index 3884f6fcf..07eeaeaca 100644 --- a/database/repositories/cve_repository.go +++ b/database/repositories/cve_repository.go @@ -137,7 +137,6 @@ func (g *cveRepository) FindAllListPaged(tx *gorm.DB, pageInfo shared.PageInfo, for _, f := range filter { q = q.Where(f.SQL(), f.Value()) } - q = q.Where("cvss > 0") q.Count(&count) // get all cves @@ -147,7 +146,6 @@ func (g *cveRepository) FindAllListPaged(tx *gorm.DB, pageInfo shared.PageInfo, for _, f := range filter { q = q.Where(f.SQL(), f.Value()) } - q = q.Where("cvss > 0") // apply sorting if len(sort) > 0 { diff --git a/router/vulndb_router.go b/router/vulndb_router.go index ef24951e5..1f15bebc5 100644 --- a/router/vulndb_router.go +++ b/router/vulndb_router.go @@ -30,7 +30,7 @@ func NewVulnDBRouter(apiV1Router APIV1Router, vulndbController *controllers.Vuln cveRouter.GET("/:cveID/", vulndbController.Read) cveRouter.GET("/purl-inspect/:purl", vulndbController.PURLInspect) cveRouter.GET("/list-ids-by-creation-date/", vulndbController.ListIDsByCreationDate) - cveRouter.GET("/affected-package-distribution/", vulndbController.GetEcosystemDistribution) + cveRouter.GET("/cve-ecosystem-distribution/", vulndbController.GetCVEEcosystemDistribution) return VulnDBRouter{ Group: cveRouter, }