Fix insufficient deduplication on vulnerabilities count query (#31021)

Fixes #27580.

# Checklist for submitter

If some of the following don't apply, delete the relevant line.

<!-- Note that API documentation changes are now addressed by the
product design team. -->

- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.
- [x] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements)
- [x] Added/updated automated tests
- [x] Manual QA for all new/changed functionality
This commit is contained in:
Ian Littman
2025-07-17 17:40:21 -05:00
committed by GitHub
parent ce02856f85
commit ab958704f7
3 changed files with 13 additions and 4 deletions
+1
View File
@@ -0,0 +1 @@
* Fixed cases where the vulnerabilities list endpoint would count the same CVE multiple times for the `count` field returned with a result set
+3 -3
View File
@@ -309,11 +309,11 @@ func (ds *Datastore) ListVulnerabilities(ctx context.Context, opt fleet.VulnList
func (ds *Datastore) CountVulnerabilities(ctx context.Context, opt fleet.VulnListOptions) (uint, error) {
selectStmt := `
SELECT
COUNT(*)
COUNT(DISTINCT combined.cve)
FROM (
SELECT cve, created_at, source FROM software_cve
SELECT cve FROM software_cve
UNION
SELECT cve, created_at, source FROM operating_system_vulnerabilities
SELECT cve FROM operating_system_vulnerabilities
) AS combined
INNER JOIN vulnerability_host_counts vhc ON vhc.cve = combined.cve
LEFT JOIN cve_meta cm ON cm.cve = combined.cve
@@ -1140,6 +1140,10 @@ func seedVulnerabilities(t *testing.T, ds *Datastore) {
CVE: "CVE-2020-1235",
ResolvedInVersion: ptr.String("1.0.1"),
},
{
SoftwareID: 2,
CVE: "CVE-2020-1235", // overlaps software ID 1
},
{
SoftwareID: 2,
CVE: "CVE-2020-1236",
@@ -1148,6 +1152,10 @@ func seedVulnerabilities(t *testing.T, ds *Datastore) {
SoftwareID: 2,
CVE: "CVE-2020-1237",
},
{
SoftwareID: 2,
CVE: "CVE-2020-1238", // overlaps between software and OS
},
}
osVulns := []fleet.OSVulnerability{
@@ -1374,7 +1382,7 @@ func seedVulnerabilities(t *testing.T, ds *Datastore) {
// Insert Software Vuln
for _, vuln := range softwareVulns {
_, err = ds.InsertSoftwareVulnerability(context.Background(), vuln, fleet.NVDSource)
_, err = ds.InsertSoftwareVulnerability(context.Background(), vuln, fleet.CustomSource)
require.NoError(t, err)
}