Skip to content

Vulndb endpoint improvements#1689

Open
Hubtrick-Git wants to merge 2 commits intomainfrom
fix-vulndb-frontend-endpoints
Open

Vulndb endpoint improvements#1689
Hubtrick-Git wants to merge 2 commits intomainfrom
fix-vulndb-frontend-endpoints

Conversation

@Hubtrick-Git
Copy link
Collaborator

  • 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

@Hubtrick-Git Hubtrick-Git self-assigned this Feb 10, 2026
Copilot AI review requested due to automatic review settings February 10, 2026 11:46
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 > 0 filtering 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.

Comment on lines +223 to +227
// 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
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Copilot uses AI. Check for mistakes.
Comment on lines +224 to +236
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
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
// 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
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Suggested change
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

Copilot uses AI. Check for mistakes.
// marshal to JSON with proper indentation
data, _ := json.MarshalIndent(aggregatedResults, "", config.PrettyJSONIndent)
return string(data)
// covert the result in a map and return it
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment says “covert the result” → “convert the result”.

Suggested change
// covert the result in a map and return it
// convert the result in a map and return it

Copilot uses AI. Check for mistakes.
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)
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant