From b51ca4b198a06364c6e91f5e973e10e5db4fa2f7 Mon Sep 17 00:00:00 2001 From: Sascha Schmerling Date: Mon, 27 Apr 2026 15:33:27 +0200 Subject: [PATCH 1/3] chore(golang-ci): Use snake case as expected format for JSON tags sqlc generates by default snake cased json tags, so make it our default expectation and add exceptions for the CVE V5 JSON format related files, since they use camel case. --- .golangci.yaml | 2 +- internal/model/cve_v5/cve_v5.go | 1 + internal/model/cvss_v2_0/cvss_v2_0.go | 1 + internal/model/cvss_v3_x/cvss_v3_x.go | 1 + internal/model/cvss_v4_0/cvss_v4_0.go | 1 + 5 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.golangci.yaml b/.golangci.yaml index eae8e35..e312bec 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -113,7 +113,7 @@ linters: tagliatelle: case: rules: - json: camel + json: snake yaml: camel xml: camel toml: camel diff --git a/internal/model/cve_v5/cve_v5.go b/internal/model/cve_v5/cve_v5.go index 6e72a72..480ed2a 100644 --- a/internal/model/cve_v5/cve_v5.go +++ b/internal/model/cve_v5/cve_v5.go @@ -1,3 +1,4 @@ +//nolint:tagliatelle // schema not defined by us package cve_v5 import ( diff --git a/internal/model/cvss_v2_0/cvss_v2_0.go b/internal/model/cvss_v2_0/cvss_v2_0.go index f647368..db84575 100644 --- a/internal/model/cvss_v2_0/cvss_v2_0.go +++ b/internal/model/cvss_v2_0/cvss_v2_0.go @@ -1,3 +1,4 @@ +//nolint:tagliatelle // schema not defined by us package cvss_v2_0 type CVSSV2_0 struct { diff --git a/internal/model/cvss_v3_x/cvss_v3_x.go b/internal/model/cvss_v3_x/cvss_v3_x.go index 64a84ef..16b8a2c 100644 --- a/internal/model/cvss_v3_x/cvss_v3_x.go +++ b/internal/model/cvss_v3_x/cvss_v3_x.go @@ -1,3 +1,4 @@ +//nolint:tagliatelle // schema not defined by us package cvss_v3_x // CVSSV3_x: 3.0 and 3.1 share the same structure, but a scored differently. diff --git a/internal/model/cvss_v4_0/cvss_v4_0.go b/internal/model/cvss_v4_0/cvss_v4_0.go index e78e434..9af938f 100644 --- a/internal/model/cvss_v4_0/cvss_v4_0.go +++ b/internal/model/cvss_v4_0/cvss_v4_0.go @@ -1,3 +1,4 @@ +//nolint:tagliatelle // schema not defined by us package cvss_v4_0 type CVSSV4_0 struct { From b17da6619a5a950f2fa52e139b942501bfbb1c99 Mon Sep 17 00:00:00 2001 From: Sascha Schmerling Date: Wed, 6 May 2026 11:46:39 +0200 Subject: [PATCH 2/3] feat(deb-sec-tracker): Ingestion and storage of Debian Triage Ingest Debian Triage data via their git repository and store it inside the sqlite database. See: https://github.com/gardenlinux/glvd2/issues/3 --- .gitignore | 4 + .gitmodules | 3 + .golangci.yaml | 5 +- Makefile | 9 +- cmd/glvd2/main.go | 21 +- config/default.yaml | 2 + go.mod | 5 +- go.sum | 6 + internal/config/config.go | 4 +- internal/db/database.go | 57 ++- internal/db/migrations/000001_init.down.sql | 6 + internal/db/migrations/000001_init.up.sql | 48 ++- internal/db/queries/cve.sql | 4 +- internal/db/queries/debiantriage.sql | 26 ++ internal/gardenlinux/glrd/glrd.go | 4 +- internal/gardenlinux/packages/packages.go | 7 +- internal/git/git_repo_service.go | 4 + internal/ingestion/cve_list_v5_ingestion.go | 2 +- .../ingestion/debsectracker/debsectracker.go | 361 ++++++++++++++++ .../debsectracker/debsectracker_test.go | 210 ++++++++++ .../debsectracker/data/CVE/list | 1 + .../emptyinputtest/expected_entries.json | 1 + .../debsectracker/data/CVE/list | 19 + .../expected_entries.json | 1 + .../debsectracker/data/CVE/list | 81 ++++ .../multipleentriestest/expected_entries.json | 387 ++++++++++++++++++ .../debsectracker/data/CVE/list | 11 + .../expected_entries.json | 61 +++ .../todotest/debsectracker/data/CVE/list | 16 + .../todotest/expected_entries.json | 38 ++ .../debsectracker/data/CVE/list | 5 + .../expected_entries.json | 1 + .../notforustest/debsectracker/data/CVE/list | 2 + .../notforustest/expected_entries.json | 13 + .../rejectedtest/debsectracker/data/CVE/list | 2 + .../rejectedtest/expected_entries.json | 1 + .../reservedtest/debsectracker/data/CVE/list | 2 + .../reservedtest/expected_entries.json | 1 + .../todonotetest/debsectracker/data/CVE/list | 2 + .../todonotetest/expected_entries.json | 13 + .../todotest/debsectracker/data/CVE/list | 16 + .../testdata/todotest/expected_entries.json | 38 ++ .../debsectracker/data/CVE/list | 13 + .../unknownformattest/expected_entries.json | 1 + .../debsectracker/data/CVE/list | 8 + .../validentrytest/expected_entries.json | 46 +++ .../debsectracker/data/CVE/list | 6 + .../expected_entries.json | 21 + .../debsectracker/data/CVE/list | 9 + .../wrongheaderlinetest/expected_entries.json | 1 + internal/model/debtriage/debtriage.go | 12 + internal/repository/cve.sql.go | 40 +- internal/repository/debiantriage.sql.go | 241 +++++++++++ internal/repository/models.go | 46 ++- sqlc.yaml | 9 + submodules/debian-security-tracker | 1 + 56 files changed, 1902 insertions(+), 52 deletions(-) create mode 100644 internal/db/queries/debiantriage.sql create mode 100644 internal/ingestion/debsectracker/debsectracker.go create mode 100644 internal/ingestion/debsectracker/debsectracker_test.go create mode 100644 internal/ingestion/debsectracker/testdata/emptyinputtest/debsectracker/data/CVE/list create mode 100644 internal/ingestion/debsectracker/testdata/emptyinputtest/expected_entries.json create mode 100644 internal/ingestion/debsectracker/testdata/missingheaderlineatstarttest/debsectracker/data/CVE/list create mode 100644 internal/ingestion/debsectracker/testdata/missingheaderlineatstarttest/expected_entries.json create mode 100644 internal/ingestion/debsectracker/testdata/multipleentriestest/debsectracker/data/CVE/list create mode 100644 internal/ingestion/debsectracker/testdata/multipleentriestest/expected_entries.json create mode 100644 internal/ingestion/debsectracker/testdata/multiplepackagesentrytest/debsectracker/data/CVE/list create mode 100644 internal/ingestion/debsectracker/testdata/multiplepackagesentrytest/expected_entries.json create mode 100644 internal/ingestion/debsectracker/testdata/multiplepackagesentrytest/todotest/debsectracker/data/CVE/list create mode 100644 internal/ingestion/debsectracker/testdata/multiplepackagesentrytest/todotest/expected_entries.json create mode 100644 internal/ingestion/debsectracker/testdata/notdisclosedskiptest/debsectracker/data/CVE/list create mode 100644 internal/ingestion/debsectracker/testdata/notdisclosedskiptest/expected_entries.json create mode 100644 internal/ingestion/debsectracker/testdata/notforustest/debsectracker/data/CVE/list create mode 100644 internal/ingestion/debsectracker/testdata/notforustest/expected_entries.json create mode 100644 internal/ingestion/debsectracker/testdata/rejectedtest/debsectracker/data/CVE/list create mode 100644 internal/ingestion/debsectracker/testdata/rejectedtest/expected_entries.json create mode 100644 internal/ingestion/debsectracker/testdata/reservedtest/debsectracker/data/CVE/list create mode 100644 internal/ingestion/debsectracker/testdata/reservedtest/expected_entries.json create mode 100644 internal/ingestion/debsectracker/testdata/todonotetest/debsectracker/data/CVE/list create mode 100644 internal/ingestion/debsectracker/testdata/todonotetest/expected_entries.json create mode 100644 internal/ingestion/debsectracker/testdata/todotest/debsectracker/data/CVE/list create mode 100644 internal/ingestion/debsectracker/testdata/todotest/expected_entries.json create mode 100644 internal/ingestion/debsectracker/testdata/unknownformattest/debsectracker/data/CVE/list create mode 100644 internal/ingestion/debsectracker/testdata/unknownformattest/expected_entries.json create mode 100644 internal/ingestion/debsectracker/testdata/validentrytest/debsectracker/data/CVE/list create mode 100644 internal/ingestion/debsectracker/testdata/validentrytest/expected_entries.json create mode 100644 internal/ingestion/debsectracker/testdata/validentrywithadvisorytest/debsectracker/data/CVE/list create mode 100644 internal/ingestion/debsectracker/testdata/validentrywithadvisorytest/expected_entries.json create mode 100644 internal/ingestion/debsectracker/testdata/wrongheaderlinetest/debsectracker/data/CVE/list create mode 100644 internal/ingestion/debsectracker/testdata/wrongheaderlinetest/expected_entries.json create mode 100644 internal/model/debtriage/debtriage.go create mode 100644 internal/repository/debiantriage.sql.go create mode 160000 submodules/debian-security-tracker diff --git a/.gitignore b/.gitignore index 227cf37..1667872 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,7 @@ bin/ # Internally used sqlite DB data/internal.sqlite + +# test code coverage +coverage.out +coverage.html diff --git a/.gitmodules b/.gitmodules index c9b875b..c9da501 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "submodules/cvelistV5"] path = submodules/cvelistV5 url = https://github.com/CVEProject/cvelistV5.git +[submodule "submodules/debian-security-tracker"] + path = submodules/debian-security-tracker + url = https://salsa.debian.org/security-tracker-team/security-tracker.git diff --git a/.golangci.yaml b/.golangci.yaml index e312bec..b9452a3 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -7,7 +7,10 @@ issues: linters: default: all + enable: + - gomodguard_v2 disable: + - gomodguard - gocognit - gocyclo - cyclop @@ -132,7 +135,7 @@ linters: - CVSSV2_0 exhaustruct: include: - - "github.com/github.com/gardenlinux/glvd2" + - "github.com/github.com/gardenlinux/glvd2" formatters: enable: diff --git a/Makefile b/Makefile index 6dd6084..4431b69 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ build: .PHONY: format format: - gofmt -l -s -w . + golangci-lint fmt .PHONY: lint lint: @@ -18,6 +18,11 @@ lint: test: clean_test go test -v ./... +.PHONY: test-coverage-html +test-coverage-html: clean_test + go test --covermode=atomic --coverprofile=coverage.out -v ./... + go tool cover -html=coverage.out + .PHONY: db_code_generate db_code_generate: sqlc generate @@ -41,4 +46,4 @@ clean_test: .PHONY: clean clean: clean_test - $(RM) $(BINARY) \ No newline at end of file + $(RM) $(BINARY) diff --git a/cmd/glvd2/main.go b/cmd/glvd2/main.go index 1a62e0b..78de1a4 100644 --- a/cmd/glvd2/main.go +++ b/cmd/glvd2/main.go @@ -12,6 +12,8 @@ import ( "github.com/gardenlinux/glvd2/internal/gardenlinux/packages" "github.com/gardenlinux/glvd2/internal/git" "github.com/gardenlinux/glvd2/internal/ingestion" + "github.com/gardenlinux/glvd2/internal/ingestion/debsectracker" + "github.com/gardenlinux/glvd2/internal/repository" "github.com/spf13/cobra" _ "modernc.org/sqlite" ) @@ -33,10 +35,8 @@ func setLogLevel(logLevelStr string) error { return nil } -func ingestCve(cfg *config.AppConfig) error { - var err error - - db, err := database.Open() +func ingestCVEs(cfg *config.AppConfig) error { + db, err := database.Regenerate(cfg.InternalSqliteDBPath) if err != nil { slog.Error("could not open database", slog.Any("error", err)) return err @@ -53,9 +53,11 @@ func ingestCve(cfg *config.AppConfig) error { return err } - // TODO: clean DB and apply migrations + queries := repository.New(db) + ctx := context.Background() + // CVEListV5 and the Debian Security Tracker are currently added as git submodules submoduleService, err := git.NewSubmoduleService(cfg) if err != nil { slog.Error("Could not initialize the submodule service", slog.Any("error", err)) @@ -67,6 +69,13 @@ func ingestCve(cfg *config.AppConfig) error { return err } + debSecTrackerIngestion := debsectracker.NewService(db, queries, cfg) + err = debSecTrackerIngestion.IngestTriage(ctx) + if err != nil { + slog.Error("Ingestion from Debian Security Tracker: %w", slog.Any("error", err)) + return err + } + cveV5Ingestion := ingestion.NewCVEV5IngestionService(cfg) resCh, errCh := cveV5Ingestion.ReceiveCVEs() tmp := "" @@ -116,7 +125,7 @@ func cmd(cfg *config.AppConfig) *cobra.Command { return err } - return ingestCve(cfg) + return ingestCVEs(cfg) }, } rootCmd.PersistentFlags().String("log-level", "error", "specify log-level") diff --git a/config/default.yaml b/config/default.yaml index b6af871..815e64f 100644 --- a/config/default.yaml +++ b/config/default.yaml @@ -1 +1,3 @@ +internal_sqlite_db_path: "./data/internal.sqlite" cve_list_v5_sub_repo_path: "./submodules/cvelistV5" +deb_sec_tracker_sub_repo_path: "./submodules/debian-security-tracker" diff --git a/go.mod b/go.mod index 8c692e5..1565625 100644 --- a/go.mod +++ b/go.mod @@ -11,16 +11,17 @@ require ( ) require ( - github.com/davecgh/go-spew v1.1.1 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/golang-migrate/migrate/v4 v4.19.1 // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/ncruces/go-strftime v1.0.0 // indirect github.com/pelletier/go-toml/v2 v2.2.4 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/rogpeppe/go-internal v1.14.1 // indirect github.com/sagikazarmark/locafero v0.11.0 // indirect diff --git a/go.sum b/go.sum index 8f20b15..69e419e 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= @@ -9,6 +11,8 @@ github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/golang-migrate/migrate/v4 v4.19.1 h1:OCyb44lFuQfYXYLx1SCxPZQGU7mcaZ7gH9yH4jSFbBA= +github.com/golang-migrate/migrate/v4 v4.19.1/go.mod h1:CTcgfjxhaUtsLipnLoQRWCrjYXycRz/g5+RWDuYgPrE= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17kjQEVQ1XRhq2/JR1M3sGqeJoxs= @@ -34,6 +38,8 @@ github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0 github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= diff --git a/internal/config/config.go b/internal/config/config.go index 5b6b12a..ceec828 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -8,7 +8,9 @@ import ( // AppConfig contains different configuration options for the application. type AppConfig struct { - CVEListV5SubRepoPath string `mapstructure:"cve_list_v5_sub_repo_path"` + CVEListV5SubRepoPath string `mapstructure:"cve_list_v5_sub_repo_path"` + DebSecTrackerSubRepoPath string `mapstructure:"deb_sec_tracker_sub_repo_path"` + InternalSqliteDBPath string `mapstructure:"internal_sqlite_db_path"` } // LoadAppConfig loads the configuration from disk. diff --git a/internal/db/database.go b/internal/db/database.go index a4e8bf0..bc6a2b8 100644 --- a/internal/db/database.go +++ b/internal/db/database.go @@ -2,12 +2,47 @@ package db import ( "database/sql" + "os" + + "github.com/golang-migrate/migrate/v4" + _ "github.com/golang-migrate/migrate/v4/database/sqlite" // blank import like lib proposes + _ "github.com/golang-migrate/migrate/v4/source/file" ) +const sqliteConnectionStringSuffix = "?journal_mode=WAL&busy_timeout=3000&secure_delete=true" + + "&foreign_keys=true&cache=shared&x-no-tx-wrap=true" + +// Regenerate clears the DB file, recreates the structure via migration, and returns a DB connection. +func Regenerate(fp string) (*sql.DB, error) { + // ensure that the file exists + f, err := os.OpenFile(fp, os.O_CREATE, 0o644) //nolint:gosec,mnd // no user input and fil + if err != nil { + return nil, err + } + if err = f.Close(); err != nil { + return nil, err + } + + // clear the file content + if err = os.Truncate(fp, 0); err != nil { + return nil, err + } + + if err = Migrate(fp); err != nil { + return nil, err + } + + db, err := Open(fp) + if err != nil { + return nil, err + } + + return db, nil +} + // Open a sqlite db from file. -func Open() (*sql.DB, error) { - db, err := sql.Open("sqlite", - "data/internal.sqlite?journal_mode=WAL&busy_timeout=3000&secure_delete=true&foreign_keys=true&cache=shared") +func Open(fp string) (*sql.DB, error) { + db, err := sql.Open("sqlite", fp+sqliteConnectionStringSuffix) if err != nil { return nil, err } @@ -17,3 +52,19 @@ func Open() (*sql.DB, error) { return db, nil } + +func Migrate(fp string) error { + m, err := migrate.New( + "file://internal/db/migrations/", + "sqlite://"+fp+sqliteConnectionStringSuffix) + if err != nil { + return err + } + + err = m.Up() + if err != nil { + return err + } + + return nil +} diff --git a/internal/db/migrations/000001_init.down.sql b/internal/db/migrations/000001_init.down.sql index 8e3f3d9..6948c88 100644 --- a/internal/db/migrations/000001_init.down.sql +++ b/internal/db/migrations/000001_init.down.sql @@ -5,4 +5,10 @@ DROP TABLE IF EXISTS product; DROP TABLE IF EXISTS affect; DROP TABLE IF EXISTS cvss_metric; +DROP TABLE IF EXISTS debian_triage; +DROP TABLE IF EXISTS debian_package; +DROP TABLE IF EXISTS debian_triage_affected_package; +DROP TABLE IF EXISTS debian_release; +DROP TABLE IF EXISTS debian_triage_affected_release; + END; diff --git a/internal/db/migrations/000001_init.up.sql b/internal/db/migrations/000001_init.up.sql index 1cad32a..a8190d3 100644 --- a/internal/db/migrations/000001_init.up.sql +++ b/internal/db/migrations/000001_init.up.sql @@ -4,8 +4,8 @@ CREATE TABLE IF NOT EXISTS cve( id TEXT PRIMARY KEY, title TEXT, description TEXT, - serial INT NOT NULL DEFAULT 1, - is_rejected INT NOT NULL DEFAULT 0, + serial INTEGER NOT NULL DEFAULT 1, + is_rejected INTEGER NOT NULL DEFAULT 0, assigner_org_id TEXT, assigner_short_name TEXT, date_reserved TEXT, @@ -16,20 +16,21 @@ CREATE TABLE IF NOT EXISTS cve( ); CREATE TABLE IF NOT EXISTS product( - id INT PRIMARY KEY, + id INTEGER PRIMARY KEY, title TEXT, cpe TEXT ); CREATE TABLE IF NOT EXISTS affect( - id INT PRIMARY KEY, + id INTEGER PRIMARY KEY, cve_id TEXT, + product_id INTEGER, FOREIGN KEY(cve_id) REFERENCES cve(id), FOREIGN KEY(product_id) REFERENCES product(id) ); CREATE TABLE IF NOT EXISTS cvss_metric( - id INT PRIMARY KEY, + id INTEGER PRIMARY KEY, cve_id TEXT, issuer TEXT, version TEXT, @@ -39,4 +40,41 @@ CREATE TABLE IF NOT EXISTS cvss_metric( FOREIGN KEY(cve_id) REFERENCES cve(id) ); +CREATE TABLE IF NOT EXISTS debian_triage( + cve_id TEXT PRIMARY KEY, + status TEXT CHECK( status IN ('UNKNOWN', 'TODO', 'REJECTED', 'NOT-FOR-US', 'PROCESSED', 'RESERVED') ) NOT NULL, + not_for_us TEXT NOT NULL, + notes TEXT NOT NULL, + to_dos TEXT NOT NULL +); + +CREATE TABLE IF NOT EXISTS debian_package( + name TEXT PRIMARY KEY +); + +CREATE TABLE IF NOT EXISTS debian_triage_affected_package( + id INTEGER PRIMARY KEY, + cve_id TEXT NOT NULL, + package_name TEXT NOT NULL, + version TEXT NOT NULL, + info TEXT, + FOREIGN KEY(cve_id) REFERENCES debian_triage(cve_id), + FOREIGN KEY(package_name) REFERENCES debian_package(name) +); + +CREATE TABLE IF NOT EXISTS debian_release( + name TEXT PRIMARY KEY +); + +CREATE TABLE IF NOT EXISTS debian_triage_affected_release( + id INTEGER PRIMARY KEY, + cve_id TEXT NOT NULL, + release_name TEXT NOT NULL, + package_name TEXT NOT NULL, + action TEXT NOT NULL, + info TEXT, + FOREIGN KEY(cve_id) REFERENCES debian_triage(cve_id), + FOREIGN KEY(release_name) REFERENCES debian_releases(name) +); + END; diff --git a/internal/db/queries/cve.sql b/internal/db/queries/cve.sql index 73b2c89..43075c1 100644 --- a/internal/db/queries/cve.sql +++ b/internal/db/queries/cve.sql @@ -1,2 +1,2 @@ --- name: ListCves :many -SELECT sqlc.embed(c) FROM cve As c ORDER BY c.name DESC; +-- name: ListCVEs :many +SELECT * FROM cve ORDER BY name DESC; diff --git a/internal/db/queries/debiantriage.sql b/internal/db/queries/debiantriage.sql new file mode 100644 index 0000000..5c1861b --- /dev/null +++ b/internal/db/queries/debiantriage.sql @@ -0,0 +1,26 @@ +-- name: GetDebianTriage :one +SELECT * FROM debian_triage WHERE cve_id = ? LIMIT 1; + +-- name: ListDebianTriages :many +SELECT * FROM debian_triage ORDER BY cve_id DESC; + +-- name: ListAffectedPackagesForDebianTriage :many +SELECT * FROM debian_triage_affected_package WHERE cve_id = ? ORDER BY id ASC; + +-- name: ListAffectedReleasesForDebianTriage :many +SELECT * FROM debian_triage_affected_release WHERE cve_id = ? ORDER BY id ASC; + +-- name: InsertDebianPackageOrIgnore :one +INSERT OR IGNORE INTO debian_package(name) VALUES (?) RETURNING *; + +-- name: InsertDebianReleaseOrIgnore :one +INSERT OR IGNORE INTO debian_release(name) VALUES (?) RETURNING *; + +-- name: InsertDebianTriage :one +INSERT INTO debian_triage(cve_id, status, not_for_us, notes, to_dos) VALUES (?, ?, ?, ?, ?) RETURNING *; + +-- name: InsertDebianTriageAffectedPackage :one +INSERT INTO debian_triage_affected_package(cve_id, package_name, version, info) VALUES (?, ?, ?, ?) RETURNING *; + +-- name: InsertDebianTriageAffectedRelease :one +INSERT INTO debian_triage_affected_release(cve_id, release_name, package_name, action, info) VALUES (?, ?, ?, ?, ?) RETURNING *; diff --git a/internal/gardenlinux/glrd/glrd.go b/internal/gardenlinux/glrd/glrd.go index 4562573..ef1e8a0 100644 --- a/internal/gardenlinux/glrd/glrd.go +++ b/internal/gardenlinux/glrd/glrd.go @@ -13,7 +13,7 @@ const glrdReleasesMinorURL = "https://gardenlinux-glrd.s3.eu-central-1.amazonaws type Git struct { Commit string `json:"commit"` - CommitShort string `json:"commit_short"` //nolint:tagliatelle // json field is defined with underscore + CommitShort string `json:"commit_short"` } type GitHub struct { @@ -37,7 +37,7 @@ type LifeCycle struct { } type Attributes struct { - SourceRepo bool `json:"source_repo"` //nolint:tagliatelle // json field is defined with underscore + SourceRepo bool `json:"source_repo"` } type Release struct { diff --git a/internal/gardenlinux/packages/packages.go b/internal/gardenlinux/packages/packages.go index 82e1c57..3078b20 100644 --- a/internal/gardenlinux/packages/packages.go +++ b/internal/gardenlinux/packages/packages.go @@ -299,7 +299,12 @@ func Cmd() (*cobra.Command, error) { } for _, pkg := range packages { - fmt.Printf("%s (%s) %s\n", pkg.Name, pkg.Architecture, pkg.Version) //nolint:revive,nolintlint,forbidigo,golines,lll // printing output for debugging + fmt.Printf( //nolint:revive,forbidigo // printing output for debugging + "%s (%s) %s\n", + pkg.Name, + pkg.Architecture, + pkg.Version, + ) } return nil }, diff --git a/internal/git/git_repo_service.go b/internal/git/git_repo_service.go index 545fb14..1dbc734 100644 --- a/internal/git/git_repo_service.go +++ b/internal/git/git_repo_service.go @@ -72,6 +72,8 @@ func fixDateIssues() error { } func (r *SubmoduleService) GetLatest(ctx context.Context) error { + slog.Info("Updating the git submodules") + err := setup(ctx) if err != nil { return err @@ -90,5 +92,7 @@ func (r *SubmoduleService) GetLatest(ctx context.Context) error { return err } + slog.Info("Finished updating the git submodules") + return nil } diff --git a/internal/ingestion/cve_list_v5_ingestion.go b/internal/ingestion/cve_list_v5_ingestion.go index 6ad6187..1566b39 100644 --- a/internal/ingestion/cve_list_v5_ingestion.go +++ b/internal/ingestion/cve_list_v5_ingestion.go @@ -30,7 +30,7 @@ func (s CVEV5IngestionService) parseJSONFile(fp string) (*cve_v5.CVEV5, error) { fp = filepath.Clean(fp) if !strings.HasPrefix(fp, filepath.Clean(s.cfg.CVEListV5SubRepoPath)) { slog.Error("Prefix does not match", - slog.String("filepath", fp), slog.String("prefix", s.cfg.CVEListV5SubRepoPath)) + slog.String("filepath", fp), slog.String("expectedPrefix", s.cfg.CVEListV5SubRepoPath)) return nil, errors.New("unsafe file path used") } jsonFile, err := os.Open(fp) diff --git a/internal/ingestion/debsectracker/debsectracker.go b/internal/ingestion/debsectracker/debsectracker.go new file mode 100644 index 0000000..2ade3d2 --- /dev/null +++ b/internal/ingestion/debsectracker/debsectracker.go @@ -0,0 +1,361 @@ +package debsectracker + +import ( + "bufio" + "context" + "database/sql" + "errors" + "fmt" + "io" + "log/slog" + "os" + "path/filepath" + "regexp" + "strings" + + "github.com/gardenlinux/glvd2/internal/config" + "github.com/gardenlinux/glvd2/internal/model/debtriage" + "github.com/gardenlinux/glvd2/internal/repository" +) + +var ( + ErrMissingHeaderLine = errors.New("missing triage entry header") + ErrUnknownHeaderLineFormat = errors.New("unknown format for a triage entry header line") + ErrUnknownFormat = errors.New("unknown format for a triage entry") +) + +type Service struct { + db *sql.DB + queries *repository.Queries + cfg *config.AppConfig +} + +func NewService(db *sql.DB, queries *repository.Queries, cfg *config.AppConfig) *Service { + return &Service{ + db: db, + queries: queries, + cfg: cfg, + } +} + +type TriageEntry struct { + Triage repository.DebianTriage `json:"debian_triage"` + AffectedPackages []repository.DebianTriageAffectedPackage `json:"affected_package"` + AffectedReleases []repository.DebianTriageAffectedRelease `json:"affected_release"` +} + +// processTriage is called by processLine once a complete triage entry is read and +// after all lines have been read to not miss the last entry. +func (s Service) processTriage(ctx context.Context, qtx *repository.Queries, entry *TriageEntry) error { + if strings.HasSuffix(entry.Triage.CVEID, "-XXXX") { + // Skipping entry, since there is no official CVE ID for it. + return nil + } + + if entry.Triage.Status == debtriage.StatusReserved || + entry.Triage.Status == debtriage.StatusRejected { + // Skipping entry, since it is not disclosed yet or was rejected. + return nil + } + + _, err := qtx.InsertDebianTriage(ctx, repository.InsertDebianTriageParams(entry.Triage)) + if err != nil { + return err + } + + for _, pkg := range entry.AffectedPackages { + _, pErr := qtx.InsertDebianPackageOrIgnore(ctx, pkg.PackageName) + if pErr != nil && !errors.Is(pErr, sql.ErrNoRows) { + return pErr + } + + _, pErr = qtx.InsertDebianTriageAffectedPackage(ctx, + repository.InsertDebianTriageAffectedPackageParams{ + // id is automatically set + CVEID: pkg.CVEID, + PackageName: pkg.PackageName, + Version: pkg.Version, + Info: pkg.Info, + }) + if pErr != nil { + return pErr + } + } + + for _, rl := range entry.AffectedReleases { + _, rErr := qtx.InsertDebianReleaseOrIgnore(ctx, rl.ReleaseName) + if rErr != nil && !errors.Is(rErr, sql.ErrNoRows) { + return rErr + } + + _, rErr = qtx.InsertDebianTriageAffectedRelease(ctx, + repository.InsertDebianTriageAffectedReleaseParams{ + CVEID: rl.CVEID, + ReleaseName: rl.ReleaseName, + PackageName: rl.PackageName, + Action: rl.Action, + Info: rl.Info, + }) + if rErr != nil { + return rErr + } + } + + return nil +} + +// CVE-YEAR-XXXX can be used, if there is not an official CVE ID yet. +var headerLineRegex = regexp.MustCompile(`^CVE-(?P\d+)-(?P\d+|XXXX).*\n$`) + +var toDoCheckRegex = regexp.MustCompile(`^\tTODO: check\n$`) + +var toDoNoteRegex = regexp.MustCompile(`^\tTODO: (?P.*)\n$`) + +var notForUsRegex = regexp.MustCompile(`^\tNOT-FOR-US: (?P.*)\n$`) + +var noteRegex = regexp.MustCompile(`^\tNOTE: (?P.*)\n$`) + +var rejectedRegex = regexp.MustCompile(`^\tREJECTED\n$`) + +var reservedRegex = regexp.MustCompile(`^\tRESERVED\n$`) + +var packageRegex = regexp.MustCompile(`^\t- (?P[^ ]+) (?P[^ ]+)( \((?P.+)\))?\n$`) + +var releaseRegex = regexp.MustCompile( + `^\t\[(?P.*)\] - (?P[^ ]+) ` + + `(?P[^ ]+)( \((?P.+)\))?\n$`) + +var advisoryRegex = regexp.MustCompile(`^\t{.*}\n$`) + +// processLine is called consecutively for all lines of the data/CVE file and calls itself processTriage once +// a triage entry has been read completely (a valid entry spans multiple lines). +func (s Service) processLine(ctx context.Context, qtx *repository.Queries, + entry *TriageEntry, line string, +) (*TriageEntry, error) { + // triage entries start with a header line like "CVE-2021-1222" + headerMatches := headerLineRegex.FindStringSubmatch(line) + if len(headerMatches) > 0 { + if entry != nil { + // process the previous triage entry, since a new one is started + err := s.processTriage(ctx, qtx, entry) + if err != nil { + return nil, err + } + } + + cveID := fmt.Sprintf("CVE-%s-%s", headerMatches[1], headerMatches[2]) + entry = &TriageEntry{ + Triage: repository.DebianTriage{ + CVEID: cveID, + Status: debtriage.StatusUnknown, + NotForUs: "", + Notes: "", + ToDos: "", + }, + AffectedPackages: []repository.DebianTriageAffectedPackage{}, + AffectedReleases: []repository.DebianTriageAffectedRelease{}, + } + + return entry, nil + } + if entry == nil { + return nil, ErrMissingHeaderLine + } + + if !strings.HasPrefix(line, "\t") { + slog.Error("Unknown format for a triage entry header line", + slog.String("ingestion", "Debian Security Tracker"), + slog.String("input", line)) + + return nil, ErrUnknownHeaderLineFormat + } + + // must now be content for a previously opened triage entry + + notForUsMatch := notForUsRegex.FindStringSubmatch(line) + if len(notForUsMatch) > 0 { + entry.Triage.Status = debtriage.StatusNotForUs + entry.Triage.NotForUs = notForUsMatch[1] + + return entry, nil + } + + packageMatch := packageRegex.FindStringSubmatch(line) + if len(packageMatch) > 0 { + entry.Triage.Status = debtriage.StatusProcessed + ap := repository.DebianTriageAffectedPackage{ + ID: -1, // ignored while insertion + CVEID: entry.Triage.CVEID, + PackageName: packageMatch[1], + Version: packageMatch[2], + Info: &packageMatch[4], + } + entry.AffectedPackages = append(entry.AffectedPackages, ap) + + return entry, nil + } + + releaseMatch := releaseRegex.FindStringSubmatch(line) + if len(releaseMatch) > 0 { + entry.Triage.Status = debtriage.StatusProcessed + ri := repository.DebianTriageAffectedRelease{ + ID: -1, // ignored while insertion + CVEID: entry.Triage.CVEID, + ReleaseName: releaseMatch[1], + PackageName: releaseMatch[2], + Action: releaseMatch[3], + Info: &releaseMatch[5], + } + entry.AffectedReleases = append(entry.AffectedReleases, ri) + + return entry, nil + } + + advisoryMatch := advisoryRegex.FindStringSubmatch(line) + if len(advisoryMatch) > 0 { + return entry, nil // not used for now + } + + toDoCheckMatch := toDoCheckRegex.FindStringSubmatch(line) + if len(toDoCheckMatch) > 0 { + entry.Triage.Status = debtriage.StatusToDo + + return entry, nil + } + + toDoNoteMatch := toDoNoteRegex.FindStringSubmatch(line) + if len(toDoNoteMatch) > 0 { + entry.Triage.ToDos += toDoNoteMatch[1] + "\n" + + return entry, nil + } + + noteMatch := noteRegex.FindStringSubmatch(line) + if len(noteMatch) > 0 { + entry.Triage.Notes += noteMatch[1] + "\n" + + return entry, nil + } + + rejectedMatch := rejectedRegex.FindStringSubmatch(line) + if len(rejectedMatch) > 0 { + entry.Triage.Status = debtriage.StatusRejected + + return entry, nil + } + + reservedMatch := reservedRegex.FindStringSubmatch(line) + if len(reservedMatch) > 0 { + entry.Triage.Status = debtriage.StatusReserved + + return entry, nil + } + + slog.Error("Unknown format for a triage entry", + slog.String("ingestion", "Debian Security Tracker"), + slog.String("input", line)) + + return nil, ErrUnknownFormat +} + +func (s Service) parseTriageList(ctx context.Context, fp string) error { + fp = filepath.Clean(fp) + if !strings.HasPrefix(fp, filepath.Clean(s.cfg.DebSecTrackerSubRepoPath)) { + slog.Error("Prefix does not match", + slog.String("filepath", fp), slog.String("expectedPrefix", s.cfg.DebSecTrackerSubRepoPath)) + return errors.New("unsafe file path used") + } + f, err := os.Open(fp) + if err != nil { + return err + } + defer func() { + if closeErr := f.Close(); closeErr != nil { + slog.Error("Error while closing file", + slog.Any("error", err)) + } + }() + + // commit all changes in one transaction to speed up the insertion + tx, err := s.db.BeginTx(ctx, &sql.TxOptions{ + Isolation: sql.LevelSerializable, + ReadOnly: false, + }) + if err != nil { + return err + } + defer func() { + if txErr := tx.Rollback(); txErr != nil && !errors.Is(txErr, sql.ErrTxDone) { + slog.Error("Error while rolling back transaction", + slog.Any("error", txErr)) + } + }() + qtx := s.queries.WithTx(tx) + + entry := (*TriageEntry)(nil) + scanner := bufio.NewReader(f) + for { + line, lErr := scanner.ReadString('\n') + if lErr == io.EOF { + if len(line) > 0 { + var lpErr error + entry, lpErr = s.processLine(ctx, qtx, entry, line) + if lpErr != nil { + return fmt.Errorf("error reading line from 'data/CVE/list': %w", lpErr) + } + } + tErr := s.processTriage(ctx, qtx, entry) // ensures that also the last entry is processed + if tErr != nil { + return tErr + } + + break + } + if lErr != nil { + return fmt.Errorf("error reading line from 'data/CVE/list': %w", lErr) + } + var lpErr error + entry, lpErr = s.processLine(ctx, qtx, entry, line) + if lpErr != nil { + return fmt.Errorf("error reading line from 'data/CVE/list': %w", lpErr) + } + } + + return tx.Commit() +} + +func (s Service) IngestTriage(ctx context.Context) error { + slog.Info("Ingesting from Debian Security Tracker") + + err := s.parseTriageList(ctx, s.cfg.DebSecTrackerSubRepoPath+"/data/CVE/list") + if err != nil { + return err + } + + slog.Info("Finished ingestion from Debian Security Tracker") + + return nil +} + +func (s Service) getTriageEntryFromDB(ctx context.Context, cveID string) (*TriageEntry, error) { + debTriage, err := s.queries.GetDebianTriage(ctx, cveID) + if err != nil { + return nil, err + } + + affectedPackages, pErr := s.queries.ListAffectedPackagesForDebianTriage(ctx, debTriage.CVEID) + if pErr != nil { + return nil, pErr + } + + affectedReleases, rErr := s.queries.ListAffectedReleasesForDebianTriage(ctx, debTriage.CVEID) + if rErr != nil { + return nil, rErr + } + + return &TriageEntry{ + Triage: debTriage, + AffectedPackages: affectedPackages, + AffectedReleases: affectedReleases, + }, nil +} diff --git a/internal/ingestion/debsectracker/debsectracker_test.go b/internal/ingestion/debsectracker/debsectracker_test.go new file mode 100644 index 0000000..b3b9673 --- /dev/null +++ b/internal/ingestion/debsectracker/debsectracker_test.go @@ -0,0 +1,210 @@ +package debsectracker_test + +import ( + "bytes" + "context" + "database/sql" + "encoding/json" + "errors" + "os" + "testing" + + "github.com/gardenlinux/glvd2/internal/config" + "github.com/gardenlinux/glvd2/internal/ingestion/debsectracker" + "github.com/gardenlinux/glvd2/internal/repository" + "github.com/golang-migrate/migrate/v4" + "github.com/golang-migrate/migrate/v4/database/sqlite" + _ "github.com/golang-migrate/migrate/v4/source/file" +) + +const sqliteConnectionStringSuffix = "?journal_mode=WAL&busy_timeout=3000&secure_delete=true" + + "&foreign_keys=true&cache=shared&x-no-tx-wrap=true" + +// getAllTriageEntriesWithRelationsFromDB: Fetches all entries in a simple way, +// so with the current implementation only recommended for tests with a limited amount of data. +func getAllTriageEntriesWithRelationsFromDB( + ctx context.Context, + queries *repository.Queries, +) ([]debsectracker.TriageEntry, error) { + entries := []debsectracker.TriageEntry{} + + debTriages, err := queries.ListDebianTriages(ctx) + if err != nil { + return nil, err + } + + for _, dt := range debTriages { + affectedPackages, pErr := queries.ListAffectedPackagesForDebianTriage(ctx, dt.CVEID) + if pErr != nil { + return nil, pErr + } + + affectedReleases, rErr := queries.ListAffectedReleasesForDebianTriage(ctx, dt.CVEID) + if rErr != nil { + return nil, rErr + } + + entries = append(entries, debsectracker.TriageEntry{ + Triage: dt, + AffectedPackages: affectedPackages, + AffectedReleases: affectedReleases, + }) + } + + return entries, nil +} + +func minifyJSON(i []byte) ([]byte, error) { + var d []any + + err := json.Unmarshal(i, &d) + if err != nil { + return nil, err + } + + o, err := json.Marshal(d) + if err != nil { + return nil, err + } + + return o, nil +} + +type IngestTriageTestCase struct { + name string // description of this test case + // Named input parameters for receiver constructor. + cfg *config.AppConfig + expectedEntriesJSONPath string + expectedError error // nil if no error is expected +} + +func genIngestTriageTestCase(name, folderName string, expectedError error) IngestTriageTestCase { + return IngestTriageTestCase{ + name: name, + cfg: &config.AppConfig{ + CVEListV5SubRepoPath: "", + DebSecTrackerSubRepoPath: "./testdata/" + folderName + "/debsectracker", + InternalSqliteDBPath: "", + }, + expectedEntriesJSONPath: "./testdata/" + folderName + "/expected_entries.json", + expectedError: expectedError, + } +} + +func TestService_IngestTriage(t *testing.T) { + t.Parallel() + tests := []IngestTriageTestCase{ + genIngestTriageTestCase("valid triage entry", "validentrytest", nil), + genIngestTriageTestCase("valid triage entry with advisory (DSA + DLA)", "validentrywithadvisorytest", nil), + genIngestTriageTestCase("valid entry with multiple packages", "multiplepackagesentrytest", nil), + genIngestTriageTestCase("valid TODO triage entry", "todotest", nil), + genIngestTriageTestCase("valid triage entry with note in TODO", "todonotetest", nil), + genIngestTriageTestCase("valid REJECTED triage entry", "rejectedtest", nil), + genIngestTriageTestCase("valid RESERVED triage entry", "reservedtest", nil), + genIngestTriageTestCase("valid NOT-FOR-US triage entry", "notforustest", nil), + genIngestTriageTestCase("not disclosed (-XXXX) entry skipped", "notdisclosedskiptest", nil), + genIngestTriageTestCase("multiple valid entries", "multipleentriestest", nil), // XXX check result + genIngestTriageTestCase( + "missing header line at start", + "missingheaderlineatstarttest", + debsectracker.ErrMissingHeaderLine, + ), + genIngestTriageTestCase( + "wrong header line format", + "wrongheaderlinetest", + debsectracker.ErrUnknownHeaderLineFormat, + ), + genIngestTriageTestCase("unknown format", "unknownformattest", debsectracker.ErrUnknownFormat), + genIngestTriageTestCase("empty input", "emptyinputtest", debsectracker.ErrMissingHeaderLine), + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + th := "IngestTriage() - " + tt.name + // in-memory test DB setup + db, err := sql.Open("sqlite", ":memory:"+sqliteConnectionStringSuffix) + if err != nil { + t.Errorf("%s: setup failed - in-memory DB creation: %v", th, err) + return + } + defer func() { + if err = db.Close(); err != nil { + t.Errorf("%s: clean up failed: %v", th, err) + } + }() + driver, err := sqlite.WithInstance( + db, + &sqlite.Config{MigrationsTable: "", DatabaseName: "", NoTxWrap: true}, + ) + if err != nil { + t.Errorf("%s: setup failed - DB driver setup for migration: %v", th, err) + return + } + m, err := migrate.NewWithDatabaseInstance( + "file://../../db/migrations/", + "sqlite", driver) + if err != nil { + t.Errorf("%s: setup failed - DB migration setup: %v", th, err) + return + } + if err = m.Up(); err != nil { + t.Errorf("%s: setup failed - DB migration: %v", th, err) + return + } + queries := repository.New(db) + + s := debsectracker.NewService(db, queries, tt.cfg) + gotErr := s.IngestTriage(context.Background()) // TODO: right context during a test? + if gotErr != nil { + if tt.expectedError != nil { + if !errors.Is(gotErr, tt.expectedError) { // XXX use specific errors + t.Errorf("%s failed with: \"%v\"; expected: \"%v\"", th, gotErr, tt.expectedError) + } + } else { + t.Errorf("%s failed with: '%v'", th, gotErr) + } + return + } + if tt.expectedError != nil { + t.Fatalf("%s succeeded unexpectedly", th) + } + + entries, err := getAllTriageEntriesWithRelationsFromDB(context.Background(), queries) + if err != nil { + t.Fatalf("%s failed: could not get the data from the DB: %v", th, err) + } + + actualJSON, err := json.Marshal(entries) + if err != nil { + t.Fatalf( + "%s failed: unexcepted problem while marshalling json the processed entries: %v", + th, + err, + ) + } + actualJSON, err = minifyJSON(actualJSON) + if err != nil { + t.Fatalf("%s failed: could not minify JSON of processed entries: %v", th, err) + } + + jb, err := os.ReadFile(tt.expectedEntriesJSONPath) + if err != nil { + t.Fatalf("%s failed: could not read JSON file with expected entries: %v", th, err) + } + + expectedJSON, err := minifyJSON(jb) + if err != nil { + t.Fatalf("%s failed: could not minify read JSON file: %v", th, err) + } + + if !bytes.Equal(actualJSON, expectedJSON) { + t.Errorf( + "%s failed: actual entries does not match the expected ones: '%s' != '%s'", + th, + actualJSON, + expectedJSON, + ) + } + }) + } +} diff --git a/internal/ingestion/debsectracker/testdata/emptyinputtest/debsectracker/data/CVE/list b/internal/ingestion/debsectracker/testdata/emptyinputtest/debsectracker/data/CVE/list new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/emptyinputtest/debsectracker/data/CVE/list @@ -0,0 +1 @@ + diff --git a/internal/ingestion/debsectracker/testdata/emptyinputtest/expected_entries.json b/internal/ingestion/debsectracker/testdata/emptyinputtest/expected_entries.json new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/emptyinputtest/expected_entries.json @@ -0,0 +1 @@ +[] diff --git a/internal/ingestion/debsectracker/testdata/missingheaderlineatstarttest/debsectracker/data/CVE/list b/internal/ingestion/debsectracker/testdata/missingheaderlineatstarttest/debsectracker/data/CVE/list new file mode 100644 index 0000000..68f21c9 --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/missingheaderlineatstarttest/debsectracker/data/CVE/list @@ -0,0 +1,19 @@ + - grub2 2.14~git20250718.0e36779-2 (bug #1105108) + [trixie] - grub2 (Minor issue) + [bookworm] - grub2 (Minor issue) + NOTE: Fixed by: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=c448f511e74cb7c776b314fcb7943f98d3f22b6d (grub-2.14-rc1) + NOTE: Additional hardening via: + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=ed691c0e0e20d9d0e8d8305a120e8c61d6be3d38 + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=7a584fbde0c339816a57d55fc165a854039cf0b2 + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=10d778c4b4d56cc36836d86a9698bc5272b12101 + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=23ec4535f40dc53f68d2709f8fb44af571431ca7 + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=301b4ef25a8fafaeba48498e97efd28bd2809f97 + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=dbc0eb5bd1f40de9b394e3a86e84f46c39a23e40 + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=73d1c959ea3417e9309ba8c6102d7d6dc7c94259 + NOTE: Option to block command line interface at build time introduced with: + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=bb65d81fe320e4b20d0a9b32232a7546eb275ecc + TODO: double check if vulnerability only considered present after grub_is_cli_disabled is introduced +CVE-2023-2311 (Insufficient policy enforcement in File System API in Google Chrome pr ...) + {DSA-5386-1} + - chromium 112.0.5615.49-1 + [buster] - chromium (see DSA 5046) diff --git a/internal/ingestion/debsectracker/testdata/missingheaderlineatstarttest/expected_entries.json b/internal/ingestion/debsectracker/testdata/missingheaderlineatstarttest/expected_entries.json new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/missingheaderlineatstarttest/expected_entries.json @@ -0,0 +1 @@ +[] diff --git a/internal/ingestion/debsectracker/testdata/multipleentriestest/debsectracker/data/CVE/list b/internal/ingestion/debsectracker/testdata/multipleentriestest/debsectracker/data/CVE/list new file mode 100644 index 0000000..fb812e2 --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/multipleentriestest/debsectracker/data/CVE/list @@ -0,0 +1,81 @@ +CVE-2026-40937 (RustFS is a distributed object storage system built in Rust. Prior to ...) + NOT-FOR-US: RustFS +CVE-2026-40517 (radare2 prior to 6.1.4 contains a command injection vulnerability in t ...) + - radare2 + NOTE: https://github.com/radareorg/radare2/issues/25730 + NOTE: https://github.com/radareorg/radare2/pull/25731 + NOTE: Fixed by: https://github.com/radareorg/radare2/commit/0e38152560e689327a74d2944fa45ba7afd4cb33 (6.1.4) +CVE-2026-6862 (A flaw was found in libefiboot, a component of efivar. The device path ...) + - efivar (bug #1134691) + NOTE: https://bugzilla.redhat.com/show_bug.cgi?id=2459982 +CVE-2026-6515 (GitLab has remediated an issue in GitLab CE/EE affecting all versions ...) + - gitlab (Only affects 18.x) +CVE-2026-35371 (The id utility in uutils coreutils exhibits incorrect behavior in its ...) + - rust-coreutils + [trixie] - rust-coreutils (Minor issue) + [bookworm] - rust-coreutils (Minor issue) + NOTE: https://github.com/uutils/coreutils/issues/10006 +CVE-2010-20110 + REJECTED +CVE-2026-40448 (Potential Integer overflow in tensor allocation size calculation could ...) + NOT-FOR-US: Samsung +CVE-2025-XXXX [OSSN-0094] + - nova 2:31.0.0-7 (bug #1111689) + [trixie] - nova 2:31.0.0-6+deb13u1 + [bookworm] - nova (Will be fixed via point release) + [bullseye] - nova (minor issue need admin right) + - watcher 14.0.0-3 (bug #1111692) + [trixie] - watcher 14.0.0-1+deb13u1 + [bookworm] - watcher (Will be fixed via point release) + NOTE: https://wiki.openstack.org/wiki/OSSN/OSSN-0094 + NOTE: https://bugs.launchpad.net/nova/+bug/2112187 + NOTE: The swap volume, live migration and all Watcher APIs are admin only so with + NOTE: default policy is only possible to create the inconsistent state described in + NOTE: the OSSN-0094 if one has admin rights on the relevant OpenStack project. +CVE-2025-38513 (In the Linux kernel, the following vulnerability has been resolved: w ...) + {DLA-4328-1 DLA-4327-1} + - linux 6.16.3-1 + [trixie] - linux 6.12.41-1 + [bookworm] - linux 6.1.147-1 + NOTE: https://git.kernel.org/linus/74b1ec9f5d627d2bdd5e5b6f3f81c23317657023 (6.16-rc6) +CVE-2025-24975 (Firebird is a relational database. Prior to snapshot versions 4.0.6.31 ...) + {DSA-5992-1} + - firebird3.0 (Vulnerable code introduced later) + - firebird4.0 4.0.6.3221.ds6-1 (bug #1111322) + NOTE: https://github.com/FirebirdSQL/firebird/security/advisories/GHSA-fx9r-rj68-7p69 + NOTE: https://github.com/FirebirdSQL/firebird/issues/8429 + NOTE: https://github.com/FirebirdSQL/firebird/commit/658abd20449f72097fbbce57e8e6ae42ff837fb6 +CVE-2023-31288 + RESERVED +CVE-2023-2311 (Insufficient policy enforcement in File System API in Google Chrome pr ...) + {DSA-5386-1} + - chromium 112.0.5615.49-1 + [buster] - chromium (see DSA 5046) +CVE-2023-31022 (NVIDIA GPU Display Driver for Windows and Linux contains a vulnerabili ...) + - nvidia-graphics-drivers 525.147.05-1 (bug #1055136) + [bookworm] - nvidia-graphics-drivers 525.147.05-1~deb12u1 + [bullseye] - nvidia-graphics-drivers 470.223.02-1 + [buster] - nvidia-graphics-drivers (Non-free not supported) + - nvidia-open-gpu-kernel-modules 525.147.05-1 (bug #1055144) + [bookworm] - nvidia-open-gpu-kernel-modules 525.147.05-1~deb12u1 + - nvidia-graphics-drivers-tesla 525.147.05-1 (bug #1055143) + [bookworm] - nvidia-graphics-drivers-tesla 525.147.05-3~deb12u1 + - nvidia-graphics-drivers-tesla-470 470.223.02-1 (bug #1055142) + [bookworm] - nvidia-graphics-drivers-tesla-470 470.223.02-1~deb12u1 + [bullseye] - nvidia-graphics-drivers-tesla-470 470.223.02-1~deb11u1 + - nvidia-graphics-drivers-tesla-460 460.106.00-3 (bug #1055141) + [bullseye] - nvidia-graphics-drivers-tesla-460 (Non-free not supported) + NOTE: 460.106.00-3 turned the package into a metapackage to aid switching to nvidia-graphics-drivers-tesla-470 + - nvidia-graphics-drivers-tesla-450 450.248.02-4 (bug #1055140) + NOTE: 450.248.02-4 turned the package into a metapackage to aid switching to nvidia-graphics-drivers-tesla-470 + [bullseye] - nvidia-graphics-drivers-tesla-450 (Non-free not supported) + - nvidia-graphics-drivers-tesla-418 (bug #1055139) + [bullseye] - nvidia-graphics-drivers-tesla-418 (Non-free not supported) + - nvidia-graphics-drivers-legacy-390xx (bug #1055138) + [bullseye] - nvidia-graphics-drivers-legacy-390xx (Non-free not supported) + [buster] - nvidia-graphics-drivers-legacy-390xx (Non-free not supported) + - nvidia-graphics-drivers-legacy-340xx (bug #1055137) + [buster] - nvidia-graphics-drivers-legacy-340xx (Non-free not supported) + NOTE: https://nvidia.custhelp.com/app/answers/detail/a_id/5491 +CVE-1999-0020 + REJECTED diff --git a/internal/ingestion/debsectracker/testdata/multipleentriestest/expected_entries.json b/internal/ingestion/debsectracker/testdata/multipleentriestest/expected_entries.json new file mode 100644 index 0000000..44b52e6 --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/multipleentriestest/expected_entries.json @@ -0,0 +1,387 @@ +[ + { + "affected_package": [ + { + "cve_id": "CVE-2026-6862", + "id": 2, + "info": "bug #1134691", + "package_name": "efivar", + "version": "" + } + ], + "affected_release": null, + "debian_triage": { + "cve_id": "CVE-2026-6862", + "not_for_us": "", + "notes": "https://bugzilla.redhat.com/show_bug.cgi?id=2459982\n", + "status": "PROCESSED", + "to_dos": "" + } + }, + { + "affected_package": [ + { + "cve_id": "CVE-2026-6515", + "id": 3, + "info": "Only affects 18.x", + "package_name": "gitlab", + "version": "" + } + ], + "affected_release": null, + "debian_triage": { + "cve_id": "CVE-2026-6515", + "not_for_us": "", + "notes": "", + "status": "PROCESSED", + "to_dos": "" + } + }, + { + "affected_package": null, + "affected_release": null, + "debian_triage": { + "cve_id": "CVE-2026-40937", + "not_for_us": "RustFS", + "notes": "", + "status": "NOT-FOR-US", + "to_dos": "" + } + }, + { + "affected_package": [ + { + "cve_id": "CVE-2026-40517", + "id": 1, + "info": "", + "package_name": "radare2", + "version": "" + } + ], + "affected_release": null, + "debian_triage": { + "cve_id": "CVE-2026-40517", + "not_for_us": "", + "notes": "https://github.com/radareorg/radare2/issues/25730\nhttps://github.com/radareorg/radare2/pull/25731\nFixed by: https://github.com/radareorg/radare2/commit/0e38152560e689327a74d2944fa45ba7afd4cb33 (6.1.4)\n", + "status": "PROCESSED", + "to_dos": "" + } + }, + { + "affected_package": null, + "affected_release": null, + "debian_triage": { + "cve_id": "CVE-2026-40448", + "not_for_us": "Samsung", + "notes": "", + "status": "NOT-FOR-US", + "to_dos": "" + } + }, + { + "affected_package": [ + { + "cve_id": "CVE-2026-35371", + "id": 4, + "info": "", + "package_name": "rust-coreutils", + "version": "" + } + ], + "affected_release": [ + { + "action": "", + "cve_id": "CVE-2026-35371", + "id": 1, + "info": "Minor issue", + "package_name": "rust-coreutils", + "release_name": "trixie" + }, + { + "action": "", + "cve_id": "CVE-2026-35371", + "id": 2, + "info": "Minor issue", + "package_name": "rust-coreutils", + "release_name": "bookworm" + } + ], + "debian_triage": { + "cve_id": "CVE-2026-35371", + "not_for_us": "", + "notes": "https://github.com/uutils/coreutils/issues/10006\n", + "status": "PROCESSED", + "to_dos": "" + } + }, + { + "affected_package": [ + { + "cve_id": "CVE-2025-38513", + "id": 5, + "info": "", + "package_name": "linux", + "version": "6.16.3-1" + } + ], + "affected_release": [ + { + "action": "6.12.41-1", + "cve_id": "CVE-2025-38513", + "id": 3, + "info": "", + "package_name": "linux", + "release_name": "trixie" + }, + { + "action": "6.1.147-1", + "cve_id": "CVE-2025-38513", + "id": 4, + "info": "", + "package_name": "linux", + "release_name": "bookworm" + } + ], + "debian_triage": { + "cve_id": "CVE-2025-38513", + "not_for_us": "", + "notes": "https://git.kernel.org/linus/74b1ec9f5d627d2bdd5e5b6f3f81c23317657023 (6.16-rc6)\n", + "status": "PROCESSED", + "to_dos": "" + } + }, + { + "affected_package": [ + { + "cve_id": "CVE-2025-24975", + "id": 6, + "info": "Vulnerable code introduced later", + "package_name": "firebird3.0", + "version": "" + }, + { + "cve_id": "CVE-2025-24975", + "id": 7, + "info": "bug #1111322", + "package_name": "firebird4.0", + "version": "4.0.6.3221.ds6-1" + } + ], + "affected_release": null, + "debian_triage": { + "cve_id": "CVE-2025-24975", + "not_for_us": "", + "notes": "https://github.com/FirebirdSQL/firebird/security/advisories/GHSA-fx9r-rj68-7p69\nhttps://github.com/FirebirdSQL/firebird/issues/8429\nhttps://github.com/FirebirdSQL/firebird/commit/658abd20449f72097fbbce57e8e6ae42ff837fb6\n", + "status": "PROCESSED", + "to_dos": "" + } + }, + { + "affected_package": [ + { + "cve_id": "CVE-2023-31022", + "id": 9, + "info": "bug #1055136", + "package_name": "nvidia-graphics-drivers", + "version": "525.147.05-1" + }, + { + "cve_id": "CVE-2023-31022", + "id": 10, + "info": "bug #1055144", + "package_name": "nvidia-open-gpu-kernel-modules", + "version": "525.147.05-1" + }, + { + "cve_id": "CVE-2023-31022", + "id": 11, + "info": "bug #1055143", + "package_name": "nvidia-graphics-drivers-tesla", + "version": "525.147.05-1" + }, + { + "cve_id": "CVE-2023-31022", + "id": 12, + "info": "bug #1055142", + "package_name": "nvidia-graphics-drivers-tesla-470", + "version": "470.223.02-1" + }, + { + "cve_id": "CVE-2023-31022", + "id": 13, + "info": "bug #1055141", + "package_name": "nvidia-graphics-drivers-tesla-460", + "version": "460.106.00-3" + }, + { + "cve_id": "CVE-2023-31022", + "id": 14, + "info": "bug #1055140", + "package_name": "nvidia-graphics-drivers-tesla-450", + "version": "450.248.02-4" + }, + { + "cve_id": "CVE-2023-31022", + "id": 15, + "info": "bug #1055139", + "package_name": "nvidia-graphics-drivers-tesla-418", + "version": "" + }, + { + "cve_id": "CVE-2023-31022", + "id": 16, + "info": "bug #1055138", + "package_name": "nvidia-graphics-drivers-legacy-390xx", + "version": "" + }, + { + "cve_id": "CVE-2023-31022", + "id": 17, + "info": "bug #1055137", + "package_name": "nvidia-graphics-drivers-legacy-340xx", + "version": "" + } + ], + "affected_release": [ + { + "action": "525.147.05-1~deb12u1", + "cve_id": "CVE-2023-31022", + "id": 6, + "info": "", + "package_name": "nvidia-graphics-drivers", + "release_name": "bookworm" + }, + { + "action": "470.223.02-1", + "cve_id": "CVE-2023-31022", + "id": 7, + "info": "", + "package_name": "nvidia-graphics-drivers", + "release_name": "bullseye" + }, + { + "action": "", + "cve_id": "CVE-2023-31022", + "id": 8, + "info": "Non-free not supported", + "package_name": "nvidia-graphics-drivers", + "release_name": "buster" + }, + { + "action": "525.147.05-1~deb12u1", + "cve_id": "CVE-2023-31022", + "id": 9, + "info": "", + "package_name": "nvidia-open-gpu-kernel-modules", + "release_name": "bookworm" + }, + { + "action": "525.147.05-3~deb12u1", + "cve_id": "CVE-2023-31022", + "id": 10, + "info": "", + "package_name": "nvidia-graphics-drivers-tesla", + "release_name": "bookworm" + }, + { + "action": "470.223.02-1~deb12u1", + "cve_id": "CVE-2023-31022", + "id": 11, + "info": "", + "package_name": "nvidia-graphics-drivers-tesla-470", + "release_name": "bookworm" + }, + { + "action": "470.223.02-1~deb11u1", + "cve_id": "CVE-2023-31022", + "id": 12, + "info": "", + "package_name": "nvidia-graphics-drivers-tesla-470", + "release_name": "bullseye" + }, + { + "action": "", + "cve_id": "CVE-2023-31022", + "id": 13, + "info": "Non-free not supported", + "package_name": "nvidia-graphics-drivers-tesla-460", + "release_name": "bullseye" + }, + { + "action": "", + "cve_id": "CVE-2023-31022", + "id": 14, + "info": "Non-free not supported", + "package_name": "nvidia-graphics-drivers-tesla-450", + "release_name": "bullseye" + }, + { + "action": "", + "cve_id": "CVE-2023-31022", + "id": 15, + "info": "Non-free not supported", + "package_name": "nvidia-graphics-drivers-tesla-418", + "release_name": "bullseye" + }, + { + "action": "", + "cve_id": "CVE-2023-31022", + "id": 16, + "info": "Non-free not supported", + "package_name": "nvidia-graphics-drivers-legacy-390xx", + "release_name": "bullseye" + }, + { + "action": "", + "cve_id": "CVE-2023-31022", + "id": 17, + "info": "Non-free not supported", + "package_name": "nvidia-graphics-drivers-legacy-390xx", + "release_name": "buster" + }, + { + "action": "", + "cve_id": "CVE-2023-31022", + "id": 18, + "info": "Non-free not supported", + "package_name": "nvidia-graphics-drivers-legacy-340xx", + "release_name": "buster" + } + ], + "debian_triage": { + "cve_id": "CVE-2023-31022", + "not_for_us": "", + "notes": "460.106.00-3 turned the package into a metapackage to aid switching to nvidia-graphics-drivers-tesla-470\n450.248.02-4 turned the package into a metapackage to aid switching to nvidia-graphics-drivers-tesla-470\nhttps://nvidia.custhelp.com/app/answers/detail/a_id/5491\n", + "status": "PROCESSED", + "to_dos": "" + } + }, + { + "affected_package": [ + { + "cve_id": "CVE-2023-2311", + "id": 8, + "info": "", + "package_name": "chromium", + "version": "112.0.5615.49-1" + } + ], + "affected_release": [ + { + "action": "", + "cve_id": "CVE-2023-2311", + "id": 5, + "info": "see DSA 5046", + "package_name": "chromium", + "release_name": "buster" + } + ], + "debian_triage": { + "cve_id": "CVE-2023-2311", + "not_for_us": "", + "notes": "", + "status": "PROCESSED", + "to_dos": "" + } + } +] diff --git a/internal/ingestion/debsectracker/testdata/multiplepackagesentrytest/debsectracker/data/CVE/list b/internal/ingestion/debsectracker/testdata/multiplepackagesentrytest/debsectracker/data/CVE/list new file mode 100644 index 0000000..8c2fbef --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/multiplepackagesentrytest/debsectracker/data/CVE/list @@ -0,0 +1,11 @@ +CVE-2022-48468 (protobuf-c before 1.4.1 has an unsigned integer overflow in parse_requ ...) + - protobuf-c 1.4.1-1 + [bullseye] - protobuf-c (Minor issue) + [buster] - protobuf-c (Minor issue) + - libsignal-protocol-c 2.3.3-3 + [bullseye] - libsignal-protocol-c (Minor issue) + [buster] - libsignal-protocol-c (Minor issue) + NOTE: https://github.com/protobuf-c/protobuf-c/commit/289f5c18b195aa43d46a619d1188709abbfa9c82 (v1.4.1) + NOTE: https://github.com/protobuf-c/protobuf-c/commit/0d1fd124a4e0a07b524989f6e64410ff648fba61 (v1.4.1) + NOTE: https://github.com/protobuf-c/protobuf-c/pull/513 + NOTE: https://github.com/protobuf-c/protobuf-c/issues/499 diff --git a/internal/ingestion/debsectracker/testdata/multiplepackagesentrytest/expected_entries.json b/internal/ingestion/debsectracker/testdata/multiplepackagesentrytest/expected_entries.json new file mode 100644 index 0000000..91f08cc --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/multiplepackagesentrytest/expected_entries.json @@ -0,0 +1,61 @@ +[ + { + "debian_triage": { + "cve_id": "CVE-2022-48468", + "not_for_us": "", + "notes": "https://github.com/protobuf-c/protobuf-c/commit/289f5c18b195aa43d46a619d1188709abbfa9c82 (v1.4.1)\nhttps://github.com/protobuf-c/protobuf-c/commit/0d1fd124a4e0a07b524989f6e64410ff648fba61 (v1.4.1)\nhttps://github.com/protobuf-c/protobuf-c/pull/513\nhttps://github.com/protobuf-c/protobuf-c/issues/499\n", + "status": "PROCESSED", + "to_dos": "" + }, + "affected_package": [ + { + "cve_id": "CVE-2022-48468", + "id": 1, + "info": "", + "package_name": "protobuf-c", + "version": "1.4.1-1" + }, + { + "cve_id": "CVE-2022-48468", + "id": 2, + "info": "", + "package_name": "libsignal-protocol-c", + "version": "2.3.3-3" + } + ], + "affected_release": [ + { + "action": "", + "cve_id": "CVE-2022-48468", + "id": 1, + "info": "Minor issue", + "package_name": "protobuf-c", + "release_name": "bullseye" + }, + { + "action": "", + "cve_id": "CVE-2022-48468", + "id": 2, + "info": "Minor issue", + "package_name": "protobuf-c", + "release_name": "buster" + }, + { + "action": "", + "cve_id": "CVE-2022-48468", + "id": 3, + "info": "Minor issue", + "package_name": "libsignal-protocol-c", + "release_name": "bullseye" + }, + { + "action": "", + "cve_id": "CVE-2022-48468", + "id": 4, + "info": "Minor issue", + "package_name": "libsignal-protocol-c", + "release_name": "buster" + } + ] + } +] diff --git a/internal/ingestion/debsectracker/testdata/multiplepackagesentrytest/todotest/debsectracker/data/CVE/list b/internal/ingestion/debsectracker/testdata/multiplepackagesentrytest/todotest/debsectracker/data/CVE/list new file mode 100644 index 0000000..f932350 --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/multiplepackagesentrytest/todotest/debsectracker/data/CVE/list @@ -0,0 +1,16 @@ +CVE-2025-4382 (A flaw was found in systems utilizing LUKS-encrypted disks with GRUB c ...) + - grub2 2.14~git20250718.0e36779-2 (bug #1105108) + [trixie] - grub2 (Minor issue) + [bookworm] - grub2 (Minor issue) + NOTE: Fixed by: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=c448f511e74cb7c776b314fcb7943f98d3f22b6d (grub-2.14-rc1) + NOTE: Additional hardening via: + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=ed691c0e0e20d9d0e8d8305a120e8c61d6be3d38 + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=7a584fbde0c339816a57d55fc165a854039cf0b2 + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=10d778c4b4d56cc36836d86a9698bc5272b12101 + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=23ec4535f40dc53f68d2709f8fb44af571431ca7 + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=301b4ef25a8fafaeba48498e97efd28bd2809f97 + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=dbc0eb5bd1f40de9b394e3a86e84f46c39a23e40 + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=73d1c959ea3417e9309ba8c6102d7d6dc7c94259 + NOTE: Option to block command line interface at build time introduced with: + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=bb65d81fe320e4b20d0a9b32232a7546eb275ecc + TODO: double check if vulnerability only considered present after grub_is_cli_disabled is introduced diff --git a/internal/ingestion/debsectracker/testdata/multiplepackagesentrytest/todotest/expected_entries.json b/internal/ingestion/debsectracker/testdata/multiplepackagesentrytest/todotest/expected_entries.json new file mode 100644 index 0000000..7bd0195 --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/multiplepackagesentrytest/todotest/expected_entries.json @@ -0,0 +1,38 @@ +[ + { + "debian_triage": { + "cve_id": "CVE-2025-4382", + "not_for_us": "", + "notes": "Fixed by: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=c448f511e74cb7c776b314fcb7943f98d3f22b6d (grub-2.14-rc1)\nAdditional hardening via:\nhttps://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=ed691c0e0e20d9d0e8d8305a120e8c61d6be3d38\nhttps://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=7a584fbde0c339816a57d55fc165a854039cf0b2\nhttps://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=10d778c4b4d56cc36836d86a9698bc5272b12101\nhttps://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=23ec4535f40dc53f68d2709f8fb44af571431ca7\nhttps://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=301b4ef25a8fafaeba48498e97efd28bd2809f97\nhttps://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=dbc0eb5bd1f40de9b394e3a86e84f46c39a23e40\nhttps://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=73d1c959ea3417e9309ba8c6102d7d6dc7c94259\nOption to block command line interface at build time introduced with:\nhttps://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=bb65d81fe320e4b20d0a9b32232a7546eb275ecc\n", + "status": "PROCESSED", + "to_dos": "double check if vulnerability only considered present after grub_is_cli_disabled is introduced\n" + }, + "affected_package": [ + { + "cve_id": "CVE-2025-4382", + "id": 1, + "info": "bug #1105108", + "package_name": "grub2", + "version": "2.14~git20250718.0e36779-2" + } + ], + "affected_release": [ + { + "action": "", + "cve_id": "CVE-2025-4382", + "id": 1, + "info": "Minor issue", + "package_name": "grub2", + "release_name": "trixie" + }, + { + "action": "", + "cve_id": "CVE-2025-4382", + "id": 2, + "info": "Minor issue", + "package_name": "grub2", + "release_name": "bookworm" + } + ] + } +] diff --git a/internal/ingestion/debsectracker/testdata/notdisclosedskiptest/debsectracker/data/CVE/list b/internal/ingestion/debsectracker/testdata/notdisclosedskiptest/debsectracker/data/CVE/list new file mode 100644 index 0000000..c3248cf --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/notdisclosedskiptest/debsectracker/data/CVE/list @@ -0,0 +1,5 @@ +CVE-2025-XXXX [RUSTSEC-2025-0020] + - rust-pyo3 0.22.6-3 (bug #1103894) + [bookworm] - rust-pyo3 (Minor issue) + NOTE: https://rustsec.org/advisories/RUSTSEC-2025-0020.html + NOTE: https://github.com/PyO3/pyo3/issues/5005 diff --git a/internal/ingestion/debsectracker/testdata/notdisclosedskiptest/expected_entries.json b/internal/ingestion/debsectracker/testdata/notdisclosedskiptest/expected_entries.json new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/notdisclosedskiptest/expected_entries.json @@ -0,0 +1 @@ +[] diff --git a/internal/ingestion/debsectracker/testdata/notforustest/debsectracker/data/CVE/list b/internal/ingestion/debsectracker/testdata/notforustest/debsectracker/data/CVE/list new file mode 100644 index 0000000..7284233 --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/notforustest/debsectracker/data/CVE/list @@ -0,0 +1,2 @@ +CVE-2026-34261 (Due to a missing authorization check in SAP Business Analytics and SAP ...) + NOT-FOR-US: SAP diff --git a/internal/ingestion/debsectracker/testdata/notforustest/expected_entries.json b/internal/ingestion/debsectracker/testdata/notforustest/expected_entries.json new file mode 100644 index 0000000..2387742 --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/notforustest/expected_entries.json @@ -0,0 +1,13 @@ +[ + { + "debian_triage": { + "cve_id": "CVE-2026-34261", + "status": "NOT-FOR-US", + "not_for_us": "SAP", + "notes": "", + "to_dos": "" + }, + "affected_package": null, + "affected_release": null + } +] diff --git a/internal/ingestion/debsectracker/testdata/rejectedtest/debsectracker/data/CVE/list b/internal/ingestion/debsectracker/testdata/rejectedtest/debsectracker/data/CVE/list new file mode 100644 index 0000000..8be3f5f --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/rejectedtest/debsectracker/data/CVE/list @@ -0,0 +1,2 @@ +CVE-2025-31523 + REJECTED diff --git a/internal/ingestion/debsectracker/testdata/rejectedtest/expected_entries.json b/internal/ingestion/debsectracker/testdata/rejectedtest/expected_entries.json new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/rejectedtest/expected_entries.json @@ -0,0 +1 @@ +[] diff --git a/internal/ingestion/debsectracker/testdata/reservedtest/debsectracker/data/CVE/list b/internal/ingestion/debsectracker/testdata/reservedtest/debsectracker/data/CVE/list new file mode 100644 index 0000000..8964f40 --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/reservedtest/debsectracker/data/CVE/list @@ -0,0 +1,2 @@ +CVE-2002-1246 + RESERVED diff --git a/internal/ingestion/debsectracker/testdata/reservedtest/expected_entries.json b/internal/ingestion/debsectracker/testdata/reservedtest/expected_entries.json new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/reservedtest/expected_entries.json @@ -0,0 +1 @@ +[] diff --git a/internal/ingestion/debsectracker/testdata/todonotetest/debsectracker/data/CVE/list b/internal/ingestion/debsectracker/testdata/todonotetest/debsectracker/data/CVE/list new file mode 100644 index 0000000..e64808d --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/todonotetest/debsectracker/data/CVE/list @@ -0,0 +1,2 @@ +CVE-2026-41179 (Rclone is a command-line program to sync files and directories to and ...) + TODO: check diff --git a/internal/ingestion/debsectracker/testdata/todonotetest/expected_entries.json b/internal/ingestion/debsectracker/testdata/todonotetest/expected_entries.json new file mode 100644 index 0000000..27dd481 --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/todonotetest/expected_entries.json @@ -0,0 +1,13 @@ +[ + { + "debian_triage": { + "cve_id": "CVE-2026-41179", + "status": "TODO", + "not_for_us": "", + "notes": "", + "to_dos": "" + }, + "affected_package": null, + "affected_release": null + } +] diff --git a/internal/ingestion/debsectracker/testdata/todotest/debsectracker/data/CVE/list b/internal/ingestion/debsectracker/testdata/todotest/debsectracker/data/CVE/list new file mode 100644 index 0000000..f932350 --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/todotest/debsectracker/data/CVE/list @@ -0,0 +1,16 @@ +CVE-2025-4382 (A flaw was found in systems utilizing LUKS-encrypted disks with GRUB c ...) + - grub2 2.14~git20250718.0e36779-2 (bug #1105108) + [trixie] - grub2 (Minor issue) + [bookworm] - grub2 (Minor issue) + NOTE: Fixed by: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=c448f511e74cb7c776b314fcb7943f98d3f22b6d (grub-2.14-rc1) + NOTE: Additional hardening via: + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=ed691c0e0e20d9d0e8d8305a120e8c61d6be3d38 + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=7a584fbde0c339816a57d55fc165a854039cf0b2 + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=10d778c4b4d56cc36836d86a9698bc5272b12101 + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=23ec4535f40dc53f68d2709f8fb44af571431ca7 + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=301b4ef25a8fafaeba48498e97efd28bd2809f97 + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=dbc0eb5bd1f40de9b394e3a86e84f46c39a23e40 + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=73d1c959ea3417e9309ba8c6102d7d6dc7c94259 + NOTE: Option to block command line interface at build time introduced with: + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=bb65d81fe320e4b20d0a9b32232a7546eb275ecc + TODO: double check if vulnerability only considered present after grub_is_cli_disabled is introduced diff --git a/internal/ingestion/debsectracker/testdata/todotest/expected_entries.json b/internal/ingestion/debsectracker/testdata/todotest/expected_entries.json new file mode 100644 index 0000000..7bd0195 --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/todotest/expected_entries.json @@ -0,0 +1,38 @@ +[ + { + "debian_triage": { + "cve_id": "CVE-2025-4382", + "not_for_us": "", + "notes": "Fixed by: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=c448f511e74cb7c776b314fcb7943f98d3f22b6d (grub-2.14-rc1)\nAdditional hardening via:\nhttps://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=ed691c0e0e20d9d0e8d8305a120e8c61d6be3d38\nhttps://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=7a584fbde0c339816a57d55fc165a854039cf0b2\nhttps://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=10d778c4b4d56cc36836d86a9698bc5272b12101\nhttps://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=23ec4535f40dc53f68d2709f8fb44af571431ca7\nhttps://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=301b4ef25a8fafaeba48498e97efd28bd2809f97\nhttps://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=dbc0eb5bd1f40de9b394e3a86e84f46c39a23e40\nhttps://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=73d1c959ea3417e9309ba8c6102d7d6dc7c94259\nOption to block command line interface at build time introduced with:\nhttps://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=bb65d81fe320e4b20d0a9b32232a7546eb275ecc\n", + "status": "PROCESSED", + "to_dos": "double check if vulnerability only considered present after grub_is_cli_disabled is introduced\n" + }, + "affected_package": [ + { + "cve_id": "CVE-2025-4382", + "id": 1, + "info": "bug #1105108", + "package_name": "grub2", + "version": "2.14~git20250718.0e36779-2" + } + ], + "affected_release": [ + { + "action": "", + "cve_id": "CVE-2025-4382", + "id": 1, + "info": "Minor issue", + "package_name": "grub2", + "release_name": "trixie" + }, + { + "action": "", + "cve_id": "CVE-2025-4382", + "id": 2, + "info": "Minor issue", + "package_name": "grub2", + "release_name": "bookworm" + } + ] + } +] diff --git a/internal/ingestion/debsectracker/testdata/unknownformattest/debsectracker/data/CVE/list b/internal/ingestion/debsectracker/testdata/unknownformattest/debsectracker/data/CVE/list new file mode 100644 index 0000000..47eb614 --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/unknownformattest/debsectracker/data/CVE/list @@ -0,0 +1,13 @@ +CVE-2026-31447 (In the Linux kernel, the following vulnerability has been resolved: e ...) + - linux 6.19.11-1 + NOTE: https://git.kernel.org/linus/3822743dc20386d9897e999dbb990befa3a5b3f8 (7.0-rc6) +CVE-2026-31446 (In the Linux kernel, the following vulnerability has been resolved: e ...) + - linux 6.19.11-1 + NOTE: https://git.kernel.org/linus/d15e4b0a418537aafa56b2cb80d44add83e83697 (7.0-rc6) +CVE-2026-31445 (In the Linux kernel, the following vulnerability has been resolved: m ...) + - linux 6.19.11-1 + [trixie] - linux (Vulnerable code not present) + [bookworm] - linux (Vulnerable code not present) + [bullseye] - linux (Vulnerable code not present) + SEVERITY: HIGH + NOTE: https://git.kernel.org/linus/26f775a054c3cda86ad465a64141894a90a9e145 (7.0-rc6) diff --git a/internal/ingestion/debsectracker/testdata/unknownformattest/expected_entries.json b/internal/ingestion/debsectracker/testdata/unknownformattest/expected_entries.json new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/unknownformattest/expected_entries.json @@ -0,0 +1 @@ +[] diff --git a/internal/ingestion/debsectracker/testdata/validentrytest/debsectracker/data/CVE/list b/internal/ingestion/debsectracker/testdata/validentrytest/debsectracker/data/CVE/list new file mode 100644 index 0000000..9d1bf99 --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/validentrytest/debsectracker/data/CVE/list @@ -0,0 +1,8 @@ +CVE-2025-15281 (Calling wordexp with WRDE_REUSE in conjunction with WRDE_APPEND in the ...) + - glibc 2.42-11 (bug #1126266) + [trixie] - glibc 2.41-12+deb13u2 + [bookworm] - glibc (Minor issue) + [bullseye] - glibc (Minor issue, unlikely scenario) + NOTE: https://www.openwall.com/lists/oss-security/2026/01/20/3 + NOTE: Introduced with: https://sourceware.org/git/?p=glibc.git;a=commit;h=8f2ece695d8822e9ecc63ecd157e90bf17a6fe65 (glibc-2.0.92) + NOTE: Fixed by: https://sourceware.org/git/?p=glibc.git;a=commit;h=80cc58ea2de214f85b0a1d902a3b668ad2ecb302 (glibc-2.43) diff --git a/internal/ingestion/debsectracker/testdata/validentrytest/expected_entries.json b/internal/ingestion/debsectracker/testdata/validentrytest/expected_entries.json new file mode 100644 index 0000000..354e2e1 --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/validentrytest/expected_entries.json @@ -0,0 +1,46 @@ +[ + { + "debian_triage": { + "cve_id": "CVE-2025-15281", + "not_for_us": "", + "notes": "https://www.openwall.com/lists/oss-security/2026/01/20/3\nIntroduced with: https://sourceware.org/git/?p=glibc.git;a=commit;h=8f2ece695d8822e9ecc63ecd157e90bf17a6fe65 (glibc-2.0.92)\nFixed by: https://sourceware.org/git/?p=glibc.git;a=commit;h=80cc58ea2de214f85b0a1d902a3b668ad2ecb302 (glibc-2.43)\n", + "status": "PROCESSED", + "to_dos": "" + }, + "affected_package": [ + { + "cve_id": "CVE-2025-15281", + "id": 1, + "info": "bug #1126266", + "package_name": "glibc", + "version": "2.42-11" + } + ], + "affected_release": [ + { + "action": "2.41-12+deb13u2", + "cve_id": "CVE-2025-15281", + "id": 1, + "info": "", + "package_name": "glibc", + "release_name": "trixie" + }, + { + "action": "", + "cve_id": "CVE-2025-15281", + "id": 2, + "info": "Minor issue", + "package_name": "glibc", + "release_name": "bookworm" + }, + { + "action": "", + "cve_id": "CVE-2025-15281", + "id": 3, + "info": "Minor issue, unlikely scenario", + "package_name": "glibc", + "release_name": "bullseye" + } + ] + } +] diff --git a/internal/ingestion/debsectracker/testdata/validentrywithadvisorytest/debsectracker/data/CVE/list b/internal/ingestion/debsectracker/testdata/validentrywithadvisorytest/debsectracker/data/CVE/list new file mode 100644 index 0000000..74478ed --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/validentrywithadvisorytest/debsectracker/data/CVE/list @@ -0,0 +1,6 @@ +CVE-2026-23952 (ImageMagick is free and open-source software used for editing and mani ...) + {DSA-6111-1 DLA-4448-1} + - imagemagick 8:7.1.2.13+dfsg1-1 (bug #1126077) + NOTE: https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-5vx3-wx4q-6cj8 + NOTE: Fixed by: https://github.com/ImageMagick/ImageMagick/commit/1eefab41bc0ab1c6c2c1fd3e4a49e3ee1849751d (7.1.2-13) + NOTE: Fixed by: https://github.com/ImageMagick/ImageMagick6/commit/0e4023775c8859d2b802e8b459a27b599ca8403a (6.9.13-38) diff --git a/internal/ingestion/debsectracker/testdata/validentrywithadvisorytest/expected_entries.json b/internal/ingestion/debsectracker/testdata/validentrywithadvisorytest/expected_entries.json new file mode 100644 index 0000000..c1a5cac --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/validentrywithadvisorytest/expected_entries.json @@ -0,0 +1,21 @@ +[ + { + "debian_triage": { + "cve_id": "CVE-2026-23952", + "not_for_us": "", + "notes": "https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-5vx3-wx4q-6cj8\nFixed by: https://github.com/ImageMagick/ImageMagick/commit/1eefab41bc0ab1c6c2c1fd3e4a49e3ee1849751d (7.1.2-13)\nFixed by: https://github.com/ImageMagick/ImageMagick6/commit/0e4023775c8859d2b802e8b459a27b599ca8403a (6.9.13-38)\n", + "status": "PROCESSED", + "to_dos": "" + }, + "affected_package": [ + { + "cve_id": "CVE-2026-23952", + "id": 1, + "info": "bug #1126077", + "package_name": "imagemagick", + "version": "8:7.1.2.13+dfsg1-1" + } + ], + "affected_release": null + } +] diff --git a/internal/ingestion/debsectracker/testdata/wrongheaderlinetest/debsectracker/data/CVE/list b/internal/ingestion/debsectracker/testdata/wrongheaderlinetest/debsectracker/data/CVE/list new file mode 100644 index 0000000..fd69f20 --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/wrongheaderlinetest/debsectracker/data/CVE/list @@ -0,0 +1,9 @@ +CVE-2023-2311 (Insufficient policy enforcement in File System API in Google Chrome pr ...) + {DSA-5386-1} + - chromium 112.0.5615.49-1 + [buster] - chromium (see DSA 5046) +GH-123-456 + - packetX 42.0 + [trixie] - grub2 (Minor issue) + [bookworm] - grub2 (Minor issue) + TODO: double check diff --git a/internal/ingestion/debsectracker/testdata/wrongheaderlinetest/expected_entries.json b/internal/ingestion/debsectracker/testdata/wrongheaderlinetest/expected_entries.json new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/wrongheaderlinetest/expected_entries.json @@ -0,0 +1 @@ +[] diff --git a/internal/model/debtriage/debtriage.go b/internal/model/debtriage/debtriage.go new file mode 100644 index 0000000..10dc074 --- /dev/null +++ b/internal/model/debtriage/debtriage.go @@ -0,0 +1,12 @@ +package debtriage + +type StatusType string + +const ( + StatusUnknown StatusType = "UNKNOWN" + StatusToDo StatusType = "TODO" + StatusRejected StatusType = "REJECTED" + StatusNotForUs StatusType = "NOT-FOR-US" + StatusProcessed StatusType = "PROCESSED" + StatusReserved StatusType = "RESERVED" +) diff --git a/internal/repository/cve.sql.go b/internal/repository/cve.sql.go index 6c91134..29231a6 100644 --- a/internal/repository/cve.sql.go +++ b/internal/repository/cve.sql.go @@ -9,36 +9,32 @@ import ( "context" ) -const listCves = `-- name: ListCves :many -SELECT c.id, c.title, c.description, c.serial, c.is_rejected, c.assigner_org_id, c.assigner_short_name, c.date_reserved, c.date_published, c.date_updated, c.date_assigned, c.date_public FROM cve As c ORDER BY c.name DESC +const listCVEs = `-- name: ListCVEs :many +SELECT id, title, description, serial, is_rejected, assigner_org_id, assigner_short_name, date_reserved, date_published, date_updated, date_assigned, date_public FROM cve ORDER BY name DESC ` -type ListCvesRow struct { - Cve Cve `json:"cve"` -} - -func (q *Queries) ListCves(ctx context.Context) ([]ListCvesRow, error) { - rows, err := q.db.QueryContext(ctx, listCves) +func (q *Queries) ListCVEs(ctx context.Context) ([]Cve, error) { + rows, err := q.db.QueryContext(ctx, listCVEs) if err != nil { return nil, err } defer rows.Close() - var items []ListCvesRow + var items []Cve for rows.Next() { - var i ListCvesRow + var i Cve if err := rows.Scan( - &i.Cve.ID, - &i.Cve.Title, - &i.Cve.Description, - &i.Cve.Serial, - &i.Cve.IsRejected, - &i.Cve.AssignerOrgID, - &i.Cve.AssignerShortName, - &i.Cve.DateReserved, - &i.Cve.DatePublished, - &i.Cve.DateUpdated, - &i.Cve.DateAssigned, - &i.Cve.DatePublic, + &i.ID, + &i.Title, + &i.Description, + &i.Serial, + &i.IsRejected, + &i.AssignerOrgID, + &i.AssignerShortName, + &i.DateReserved, + &i.DatePublished, + &i.DateUpdated, + &i.DateAssigned, + &i.DatePublic, ); err != nil { return nil, err } diff --git a/internal/repository/debiantriage.sql.go b/internal/repository/debiantriage.sql.go new file mode 100644 index 0000000..28f181e --- /dev/null +++ b/internal/repository/debiantriage.sql.go @@ -0,0 +1,241 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.30.0 +// source: debiantriage.sql + +package repository + +import ( + "context" + + debtriage "github.com/gardenlinux/glvd2/internal/model/debtriage" +) + +const getDebianTriage = `-- name: GetDebianTriage :one +SELECT cve_id, status, not_for_us, notes, to_dos FROM debian_triage WHERE cve_id = ? LIMIT 1 +` + +func (q *Queries) GetDebianTriage(ctx context.Context, cveID string) (DebianTriage, error) { + row := q.db.QueryRowContext(ctx, getDebianTriage, cveID) + var i DebianTriage + err := row.Scan( + &i.CVEID, + &i.Status, + &i.NotForUs, + &i.Notes, + &i.ToDos, + ) + return i, err +} + +const insertDebianPackageOrIgnore = `-- name: InsertDebianPackageOrIgnore :one +INSERT OR IGNORE INTO debian_package(name) VALUES (?) RETURNING name +` + +func (q *Queries) InsertDebianPackageOrIgnore(ctx context.Context, name string) (string, error) { + row := q.db.QueryRowContext(ctx, insertDebianPackageOrIgnore, name) + err := row.Scan(&name) + return name, err +} + +const insertDebianReleaseOrIgnore = `-- name: InsertDebianReleaseOrIgnore :one +INSERT OR IGNORE INTO debian_release(name) VALUES (?) RETURNING name +` + +func (q *Queries) InsertDebianReleaseOrIgnore(ctx context.Context, name string) (string, error) { + row := q.db.QueryRowContext(ctx, insertDebianReleaseOrIgnore, name) + err := row.Scan(&name) + return name, err +} + +const insertDebianTriage = `-- name: InsertDebianTriage :one +INSERT INTO debian_triage(cve_id, status, not_for_us, notes, to_dos) VALUES (?, ?, ?, ?, ?) RETURNING cve_id, status, not_for_us, notes, to_dos +` + +type InsertDebianTriageParams struct { + CVEID string `json:"cve_id"` + Status debtriage.StatusType `json:"status"` + NotForUs string `json:"not_for_us"` + Notes string `json:"notes"` + ToDos string `json:"to_dos"` +} + +func (q *Queries) InsertDebianTriage(ctx context.Context, arg InsertDebianTriageParams) (DebianTriage, error) { + row := q.db.QueryRowContext(ctx, insertDebianTriage, + arg.CVEID, + arg.Status, + arg.NotForUs, + arg.Notes, + arg.ToDos, + ) + var i DebianTriage + err := row.Scan( + &i.CVEID, + &i.Status, + &i.NotForUs, + &i.Notes, + &i.ToDos, + ) + return i, err +} + +const insertDebianTriageAffectedPackage = `-- name: InsertDebianTriageAffectedPackage :one +INSERT INTO debian_triage_affected_package(cve_id, package_name, version, info) VALUES (?, ?, ?, ?) RETURNING id, cve_id, package_name, version, info +` + +type InsertDebianTriageAffectedPackageParams struct { + CVEID string `json:"cve_id"` + PackageName string `json:"package_name"` + Version string `json:"version"` + Info *string `json:"info"` +} + +func (q *Queries) InsertDebianTriageAffectedPackage(ctx context.Context, arg InsertDebianTriageAffectedPackageParams) (DebianTriageAffectedPackage, error) { + row := q.db.QueryRowContext(ctx, insertDebianTriageAffectedPackage, + arg.CVEID, + arg.PackageName, + arg.Version, + arg.Info, + ) + var i DebianTriageAffectedPackage + err := row.Scan( + &i.ID, + &i.CVEID, + &i.PackageName, + &i.Version, + &i.Info, + ) + return i, err +} + +const insertDebianTriageAffectedRelease = `-- name: InsertDebianTriageAffectedRelease :one +INSERT INTO debian_triage_affected_release(cve_id, release_name, package_name, action, info) VALUES (?, ?, ?, ?, ?) RETURNING id, cve_id, release_name, package_name, "action", info +` + +type InsertDebianTriageAffectedReleaseParams struct { + CVEID string `json:"cve_id"` + ReleaseName string `json:"release_name"` + PackageName string `json:"package_name"` + Action string `json:"action"` + Info *string `json:"info"` +} + +func (q *Queries) InsertDebianTriageAffectedRelease(ctx context.Context, arg InsertDebianTriageAffectedReleaseParams) (DebianTriageAffectedRelease, error) { + row := q.db.QueryRowContext(ctx, insertDebianTriageAffectedRelease, + arg.CVEID, + arg.ReleaseName, + arg.PackageName, + arg.Action, + arg.Info, + ) + var i DebianTriageAffectedRelease + err := row.Scan( + &i.ID, + &i.CVEID, + &i.ReleaseName, + &i.PackageName, + &i.Action, + &i.Info, + ) + return i, err +} + +const listAffectedPackagesForDebianTriage = `-- name: ListAffectedPackagesForDebianTriage :many +SELECT id, cve_id, package_name, version, info FROM debian_triage_affected_package WHERE cve_id = ? ORDER BY id ASC +` + +func (q *Queries) ListAffectedPackagesForDebianTriage(ctx context.Context, cveID string) ([]DebianTriageAffectedPackage, error) { + rows, err := q.db.QueryContext(ctx, listAffectedPackagesForDebianTriage, cveID) + if err != nil { + return nil, err + } + defer rows.Close() + var items []DebianTriageAffectedPackage + for rows.Next() { + var i DebianTriageAffectedPackage + if err := rows.Scan( + &i.ID, + &i.CVEID, + &i.PackageName, + &i.Version, + &i.Info, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const listAffectedReleasesForDebianTriage = `-- name: ListAffectedReleasesForDebianTriage :many +SELECT id, cve_id, release_name, package_name, "action", info FROM debian_triage_affected_release WHERE cve_id = ? ORDER BY id ASC +` + +func (q *Queries) ListAffectedReleasesForDebianTriage(ctx context.Context, cveID string) ([]DebianTriageAffectedRelease, error) { + rows, err := q.db.QueryContext(ctx, listAffectedReleasesForDebianTriage, cveID) + if err != nil { + return nil, err + } + defer rows.Close() + var items []DebianTriageAffectedRelease + for rows.Next() { + var i DebianTriageAffectedRelease + if err := rows.Scan( + &i.ID, + &i.CVEID, + &i.ReleaseName, + &i.PackageName, + &i.Action, + &i.Info, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const listDebianTriages = `-- name: ListDebianTriages :many +SELECT cve_id, status, not_for_us, notes, to_dos FROM debian_triage ORDER BY cve_id DESC +` + +func (q *Queries) ListDebianTriages(ctx context.Context) ([]DebianTriage, error) { + rows, err := q.db.QueryContext(ctx, listDebianTriages) + if err != nil { + return nil, err + } + defer rows.Close() + var items []DebianTriage + for rows.Next() { + var i DebianTriage + if err := rows.Scan( + &i.CVEID, + &i.Status, + &i.NotForUs, + &i.Notes, + &i.ToDos, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} diff --git a/internal/repository/models.go b/internal/repository/models.go index 1dbd0e4..3006069 100644 --- a/internal/repository/models.go +++ b/internal/repository/models.go @@ -4,9 +4,14 @@ package repository +import ( + debtriage "github.com/gardenlinux/glvd2/internal/model/debtriage" +) + type Affect struct { - ID int64 `json:"id"` - CveID *string `json:"cve_id"` + ID int64 `json:"id"` + CVEID *string `json:"cve_id"` + ProductID *int64 `json:"product_id"` } type Cve struct { @@ -26,7 +31,7 @@ type Cve struct { type CvssMetric struct { ID int64 `json:"id"` - CveID *string `json:"cve_id"` + CVEID *string `json:"cve_id"` Issuer *string `json:"issuer"` Version *string `json:"version"` VectorString *string `json:"vector_string"` @@ -34,8 +39,41 @@ type CvssMetric struct { BaseSeverity *string `json:"base_severity"` } +type DebianPackage struct { + Name string `json:"name"` +} + +type DebianRelease struct { + Name string `json:"name"` +} + +type DebianTriage struct { + CVEID string `json:"cve_id"` + Status debtriage.StatusType `json:"status"` + NotForUs string `json:"not_for_us"` + Notes string `json:"notes"` + ToDos string `json:"to_dos"` +} + +type DebianTriageAffectedPackage struct { + ID int64 `json:"id"` + CVEID string `json:"cve_id"` + PackageName string `json:"package_name"` + Version string `json:"version"` + Info *string `json:"info"` +} + +type DebianTriageAffectedRelease struct { + ID int64 `json:"id"` + CVEID string `json:"cve_id"` + ReleaseName string `json:"release_name"` + PackageName string `json:"package_name"` + Action string `json:"action"` + Info *string `json:"info"` +} + type Product struct { ID int64 `json:"id"` Title *string `json:"title"` - Cpe *string `json:"cpe"` + CPE *string `json:"cpe"` } diff --git a/sqlc.yaml b/sqlc.yaml index d73cdd0..f036428 100644 --- a/sqlc.yaml +++ b/sqlc.yaml @@ -11,3 +11,12 @@ sql: emit_json_tags: true emit_enum_valid_method: true emit_all_enum_values: true + rename: + cve_id: "CVEID" + cpe: "CPE" + overrides: + - column: "debian_triage.status" + go_type: + import: "github.com/gardenlinux/glvd2/internal/model/debtriage" + package: "debtriage" + type: "StatusType" diff --git a/submodules/debian-security-tracker b/submodules/debian-security-tracker new file mode 160000 index 0000000..8788c5f --- /dev/null +++ b/submodules/debian-security-tracker @@ -0,0 +1 @@ +Subproject commit 8788c5fb8b6b1d17f0b6e519d575330fd4d8d349 From 557dc0d9c8d0fdd12b770d768ab916b387cfcea6 Mon Sep 17 00:00:00 2001 From: Sascha Schmerling Date: Thu, 7 May 2026 10:34:51 +0200 Subject: [PATCH 3/3] fix(db): Wrong table used in setup SQL for debian_release-relation --- internal/db/migrations/000001_init.up.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/db/migrations/000001_init.up.sql b/internal/db/migrations/000001_init.up.sql index a8190d3..648884a 100644 --- a/internal/db/migrations/000001_init.up.sql +++ b/internal/db/migrations/000001_init.up.sql @@ -74,7 +74,7 @@ CREATE TABLE IF NOT EXISTS debian_triage_affected_release( action TEXT NOT NULL, info TEXT, FOREIGN KEY(cve_id) REFERENCES debian_triage(cve_id), - FOREIGN KEY(release_name) REFERENCES debian_releases(name) + FOREIGN KEY(release_name) REFERENCES debian_release(name) ); END;