fleet/server/vulnerabilities/goval_dictionary/database_test.go
Konstantin Sykulev bd2b2bcd3b
validate generate-cve.yml outputs (#26752)
https://github.com/fleetdm/fleet/issues/21300

- [x] Added/updated automated tests
- [x] A detailed QA plan exists on the associated ticket (if it isn't
there, work with the product group's QA engineer to add it)
- [x] Manual QA for all new/changed functionality
2025-03-12 14:49:47 -05:00

121 lines
4.8 KiB
Go

package goval_dictionary
import (
"database/sql"
"testing"
"github.com/fleetdm/fleet/v4/server/fleet"
"github.com/fleetdm/fleet/v4/server/vulnerabilities/oval"
kitlog "github.com/go-kit/log"
"github.com/stretchr/testify/require"
)
func TestVerify(t *testing.T) {
sqlite, err := sql.Open("sqlite3", ":memory:")
if err != nil {
t.Fatal(err)
}
// notice how we are missing the packages.version column
dbSetupQueries := []string{
"CREATE TABLE packages (name TEXT NOT NULL, arch TEXT NOT NULL, definition_id INTEGER NOT NULL)",
"CREATE TABLE definitions (id INTEGER NOT NULL PRIMARY KEY)",
"CREATE TABLE advisories (id INTEGER NOT NULL PRIMARY KEY, definition_id INTEGER NOT NULL)",
"CREATE TABLE cves (cve_id TEXT NOT NULL, advisory_id INTEGER NOT NULL)",
}
for _, query := range dbSetupQueries {
if _, err := sqlite.Exec(query); err != nil {
t.Fatal(err)
}
}
db := NewDB(sqlite, oval.NewPlatform("amzn", "Amazon Linux 2.0.0"))
t.Run("Verify alerts of error", func(t *testing.T) {
require.Error(t, db.Verfiy())
})
}
func TestDatabase(t *testing.T) {
// build minimal slice of goval-dictionary sqlite schema
sqlite, err := sql.Open("sqlite3", ":memory:")
if err != nil {
t.Fatal(err)
}
dbSetupQueries := []string{
// create schema
"CREATE TABLE packages (name TEXT NOT NULL, arch TEXT NOT NULL, version TEXT NOT NULL, definition_id INTEGER NOT NULL)",
"CREATE TABLE definitions (id INTEGER NOT NULL PRIMARY KEY)",
"CREATE TABLE advisories (id INTEGER NOT NULL PRIMARY KEY, definition_id INTEGER NOT NULL)",
"CREATE TABLE cves (cve_id TEXT NOT NULL, advisory_id INTEGER NOT NULL)",
// insert records
`INSERT INTO packages (name, arch, version, definition_id) VALUES
('expat', 'aarch64', '0:2.1.0-15.amzn2.0.3', 1), ('krb5-server', 'aarch64', '0:1.15.1-55.amzn2.2.8', 2)`,
"INSERT INTO definitions (id) VALUES (1), (2)",
"INSERT INTO advisories (id, definition_id) VALUES (1, 1), (2, 2)",
`INSERT INTO cves (cve_id, advisory_id) VALUES
('CVE-2022-23990', 1), ('CVE-2022-25313', 1), ('CVE-2024-37370', 2), ('CVE-2024-37371', 2)`,
}
for _, query := range dbSetupQueries {
if _, err := sqlite.Exec(query); err != nil {
t.Fatal(err)
}
}
db := NewDB(sqlite, oval.NewPlatform("amzn", "Amazon Linux 2.0.0"))
logger := kitlog.NewNopLogger()
t.Run("Non-matching architecture", func(t *testing.T) {
require.Len(t, db.Eval([]fleet.Software{{Name: "expat", Version: "2.1.0", Release: "", Arch: "x86_64"}}, logger), 0)
})
t.Run("Non-matching package name", func(t *testing.T) {
require.Len(t, db.Eval([]fleet.Software{{Name: "expath", Version: "2.1.0", Release: "", Arch: "aarch64"}}, logger), 0)
})
t.Run("Fixed version", func(t *testing.T) {
require.Len(t, db.Eval([]fleet.Software{{Name: "expath", Version: "2.1.0", Release: "15.amzn2.0.3", Arch: "aarch64"}}, logger), 0)
})
t.Run("Newer than fixed version", func(t *testing.T) {
require.Len(t, db.Eval([]fleet.Software{{Name: "expath", Version: "2.1.0", Release: "15.amzn2.0.5", Arch: "aarch64"}}, logger), 0)
})
t.Run("Older than fixed version", func(t *testing.T) {
vulns := db.Eval([]fleet.Software{{Name: "expat", Version: "2.1.0", Release: "", Arch: "aarch64", ID: 123}}, logger)
require.Len(t, vulns, 2)
require.Equal(t, "2.1.0-15.amzn2.0.3", *vulns[0].ResolvedInVersion)
require.Equal(t, "2.1.0-15.amzn2.0.3", *vulns[1].ResolvedInVersion)
require.Equal(t, "CVE-2022-23990", vulns[0].CVE)
require.Equal(t, "CVE-2022-25313", vulns[1].CVE)
require.Equal(t, uint(123), vulns[0].SoftwareID)
require.Equal(t, uint(123), vulns[1].SoftwareID)
})
t.Run("Multiple packages, fixed version", func(t *testing.T) {
require.Len(t, db.Eval([]fleet.Software{
{Name: "expat", Version: "2.1.0", Release: "15.amzn2.1.0", Arch: "aarch64"},
{Name: "krb5-server", Version: "1.15.1", Release: "55.amzn2.2.8", Arch: "aarch64"},
}, logger), 0)
})
t.Run("Multiple packages, multiple vulnerabilities", func(t *testing.T) {
vulns := db.Eval([]fleet.Software{
{Name: "expat", Version: "2.1.0", Release: "15.amzn2.0.2", Arch: "aarch64", ID: 234},
{Name: "krb5-server", Version: "1.15.1", Release: "55.amzn2.2.7", Arch: "aarch64", ID: 235},
}, logger)
require.Len(t, vulns, 4)
require.Equal(t, "2.1.0-15.amzn2.0.3", *vulns[0].ResolvedInVersion)
require.Equal(t, "2.1.0-15.amzn2.0.3", *vulns[1].ResolvedInVersion)
require.Equal(t, "1.15.1-55.amzn2.2.8", *vulns[2].ResolvedInVersion)
require.Equal(t, "CVE-2022-23990", vulns[0].CVE)
require.Equal(t, "CVE-2022-25313", vulns[1].CVE)
require.Equal(t, "CVE-2024-37370", vulns[2].CVE)
require.Equal(t, "CVE-2024-37371", vulns[3].CVE)
require.Equal(t, uint(234), vulns[0].SoftwareID)
require.Equal(t, uint(234), vulns[1].SoftwareID)
require.Equal(t, uint(235), vulns[2].SoftwareID)
require.Equal(t, uint(235), vulns[3].SoftwareID)
})
t.Run("Verify returns no errors", func(t *testing.T) {
require.NoError(t, db.Verfiy())
})
}