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.
| // 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 |
There was a problem hiding this comment.
The SQL counts rows in the join table (COUNT(*)), which will count one CVE multiple times if it affects multiple components within the same ecosystem. If the intent is “number of vulnerabilities per ecosystem”, this should likely be COUNT(DISTINCT a.cvecve) (or clarify the metric in naming/docs).
| 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.
| // 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 |
There was a problem hiding this comment.
For the malicious packages query, COUNT(*) will count affected-component rows, not malicious packages. If the intent is to include malicious packages in the distribution, consider COUNT(DISTINCT a.id) / COUNT(DISTINCT b.malicious_package_id) depending on the desired metric (packages vs component entries).
| maliciousPackagesSQL := `SELECT LOWER(b.ecosystem) as ecosystem, COUNT(*) FROM malicious_packages a | |
| maliciousPackagesSQL := `SELECT LOWER(b.ecosystem) as ecosystem, COUNT(DISTINCT a.id) FROM malicious_packages a |
| // marshal to JSON with proper indentation | ||
| data, _ := json.MarshalIndent(aggregatedResults, "", config.PrettyJSONIndent) | ||
| return string(data) | ||
| // covert the result in a map and return it |
There was a problem hiding this comment.
The comment says “covert the result” → “convert the result”.
| // covert the result in a map and return it | |
| // convert the result in a map and return it |
| 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) |
There was a problem hiding this comment.
The PR description refers to the “package distribution endpoint”, but this route was renamed to /cve-ecosystem-distribution/ and the handler name suggests it now returns CVE/vulnerability counts. Please confirm the intended public API semantics here (packages vs vulnerabilities) and consider keeping the old path as an alias (or updating any API docs/clients) if this wasn’t meant to be a breaking change.