Vulndb endpoint improvements#1689
Conversation
Hubtrick-Git
commented
Feb 10, 2026
- Removed filtering of cves with cvss <= 0
- Adjusted the package distribution endpoint to also include malicious packages
- Simplified Package distribution endpoint by cutting json formatting
There was a problem hiding this comment.
Pull request overview
This PR updates the VulnDB API behavior by widening CVE list results (no longer excluding CVEs with non-positive CVSS) and reworking the ecosystem distribution endpoint to incorporate malicious package data while simplifying JSON rendering.
Changes:
- Remove
cvss > 0filtering from paginated CVE listing queries. - Replace the previous “affected package distribution” endpoint with a new
/cve-ecosystem-distribution/endpoint. - Rework the ecosystem distribution handler to query CVE/component relations plus malicious package data and return JSON via
ctx.JSONPretty.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
| router/vulndb_router.go | Renames and rewires the VulnDB distribution endpoint route to the new handler. |
| database/repositories/cve_repository.go | Removes the repository-level cvss > 0 filter from paged CVE listing. |
| controllers/vulndb_controller.go | Implements the new ecosystem distribution handler, including malicious package aggregation and JSONPretty output. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| 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 |
There was a problem hiding this comment.
ecosystem is nullable in both affected_components and malicious_affected_components tables, but the query groups by LOWER(b.ecosystem) without filtering NULL/empty values. This can yield a NULL/empty ecosystem bucket that later gets mapped to an empty-string key; consider adding WHERE b.ecosystem IS NOT NULL AND b.ecosystem <> '' (and similarly for the malicious packages query) to avoid returning an ambiguous "" ecosystem.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Tim Bastin <38261809+timbastin@users.noreply.github.com>