|
| 1 | +// Copyright (C) 2026 l3montree GmbH |
| 2 | +// |
| 3 | +// This program is free software: you can redistribute it and/or modify |
| 4 | +// it under the terms of the GNU Affero General Public License as |
| 5 | +// published by the Free Software Foundation, either version 3 of the |
| 6 | +// License, or (at your option) any later version. |
| 7 | +// |
| 8 | +// This program is distributed in the hope that it will be useful, |
| 9 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 10 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 11 | +// GNU Affero General Public License for more details. |
| 12 | +// |
| 13 | +// You should have received a copy of the GNU Affero General Public License |
| 14 | +// along with this program. If not, see <https://www.gnu.org/licenses/>. |
| 15 | +package vulndb |
| 16 | + |
| 17 | +import ( |
| 18 | + "bytes" |
| 19 | + "encoding/json" |
| 20 | + "os" |
| 21 | + "testing" |
| 22 | + "time" |
| 23 | + |
| 24 | + "github.com/l3montree-dev/devguard/dtos" |
| 25 | + "github.com/l3montree-dev/devguard/transformer" |
| 26 | +) |
| 27 | + |
| 28 | +/* |
| 29 | +5:47AM ERR vulndb/integrity.go:116 invalid checksum when importing table=exploits expectedCount=8523 actualCount=8531 expectedChecksum=6232333932343434376236666336666535663665393965313334633335303563 actualChecksum=3335373562623638303565326630343838356534663462636435656662633461 |
| 30 | +5:47AM ERR vulndb/integrity.go:116 invalid checksum when importing table=cve_relationships expectedCount=215759 actualCount=215788 expectedChecksum=6439313364643532363862326331373839346234343838356536316238643034 actualChecksum=3766303064303736356131643233663934343961316231366364373664376337 |
| 31 | +5:47AM ERR vulndb/integrity.go:116 invalid checksum when importing table=affected_components expectedCount=2161081 actualCount=2161314 expectedChecksum=3730363337353037646331346366346436376539383930636664643338393630 actualChecksum=3931396231656432336331393661663066343634613062343638633038376663 |
| 32 | +5:47AM ERR vulndb/integrity.go:116 invalid checksum when importing table=cves expectedCount=177924 actualCount=177937 expectedChecksum=3763393961343964323137366431336632653134373566363138373365313061 actualChecksum=3639396336643561346561343866313334656338393461323435343439316636 |
| 33 | +5:47AM ERR vulndb/integrity.go:116 invalid checksum when importing table=cve_affected_component expectedCount=9495979 actualCount=9496443 expectedChecksum=3330326465346438323864633837303139656665633963366138316538343535 actualChecksum=6564616333633034393337363539613938633833333666313933303361663438 |
| 34 | +
|
| 35 | +There are MORE cves in the database after the import than expected expectedCount=177924 actualCount=177937 |
| 36 | +*/ |
| 37 | +func TestImportRC(t *testing.T) { |
| 38 | + // extract the vulndb.tar.zst fixture to a temp dir |
| 39 | + if _, err := os.Stat("vulndb-testdata-new"); os.IsNotExist(err) { |
| 40 | + if err := untarZstd("vulndb-new.tar.zst", "vulndb-testdata-new"); err != nil { |
| 41 | + t.Fatalf("could not extract vulndb testdata: %v", err) |
| 42 | + } |
| 43 | + } |
| 44 | + /*lastImportTime, err := time.Parse(time.RFC3339Nano, "2026-05-10T05:10:29.831137845Z") |
| 45 | + if err != nil { |
| 46 | + t.Fatalf("could not parse last import time: %v", err) |
| 47 | + }*/ |
| 48 | + /* |
| 49 | +
|
| 50 | + Okay ich habe keine Ahnung was ich hier tppe |
| 51 | + */ |
| 52 | + |
| 53 | + currentStateFile, err := os.ReadFile("prod-db-cves-full.csv") |
| 54 | + if err != nil { |
| 55 | + t.Fatalf("could not read current state file: %v", err) |
| 56 | + } |
| 57 | + // split into lines |
| 58 | + lines := bytes.Split(currentStateFile, []byte{'\n'}) |
| 59 | + // remove the first line (header) |
| 60 | + lines = lines[1:] |
| 61 | + |
| 62 | + // read the whole osv.go file and check what cves we would insert right now |
| 63 | + osvEntries, err := readAllGobItems[OSVEntry]("vulndb-testdata-new/osv.gob") |
| 64 | + if err != nil { |
| 65 | + t.Fatalf("could not read osv gob file: %v", err) |
| 66 | + } |
| 67 | + |
| 68 | + // remove all malicious packages and components from the osvEntries, as they are not part of the RC import |
| 69 | + filteredOSVEntries := make([]OSVEntry, 0, len(osvEntries)) |
| 70 | + for _, entry := range osvEntries { |
| 71 | + if !bytes.HasPrefix([]byte(entry.OSV.ID), []byte("MAL-")) { |
| 72 | + filteredOSVEntries = append(filteredOSVEntries, entry) |
| 73 | + } |
| 74 | + } |
| 75 | + // check what cves we would insert right now |
| 76 | + cves := gobOSVToVulnFilterTransformer(time.Time{}, nil)(filteredOSVEntries) |
| 77 | + |
| 78 | + // check which cves we would insert right now are not in the current state file |
| 79 | + currentStateMap := make(map[string]struct{}) |
| 80 | + for _, line := range lines { |
| 81 | + // split by comma and get the first column (cve id) |
| 82 | + columns := bytes.Split(line, []byte{','}) |
| 83 | + if len(columns) > 0 { |
| 84 | + currentStateMap[string(columns[0])] = struct{}{} |
| 85 | + } |
| 86 | + } |
| 87 | + |
| 88 | + newStateMap := make(map[string]struct{}) |
| 89 | + for _, cve := range cves.CVEs { |
| 90 | + newStateMap[cve.CVE] = struct{}{} |
| 91 | + } |
| 92 | + |
| 93 | + // check which cves are in the currentStateMap but not in the newStateMap |
| 94 | + for cve := range currentStateMap { |
| 95 | + if _, exist := newStateMap[cve]; !exist { |
| 96 | + t.Logf("CVE in current state but not in new state: %s", cve) |
| 97 | + } |
| 98 | + } |
| 99 | + t.Fail() |
| 100 | +} |
| 101 | + |
| 102 | +/* |
| 103 | +--- FAIL: TestImportRC (3.85s) |
| 104 | + /Users/timbastin/Desktop/l3montree/devguard/vulndb/import_test.go:88: CVE in current state but not in new state: ECHO-579f-8639-173e |
| 105 | + /Users/timbastin/Desktop/l3montree/devguard/vulndb/import_test.go:88: CVE in current state but not in new state: ECHO-e780-297e-3c37 |
| 106 | + /Users/timbastin/Desktop/l3montree/devguard/vulndb/import_test.go:88: CVE in current state but not in new state: ECHO-01ac-8821-274a |
| 107 | + /Users/timbastin/Desktop/l3montree/devguard/vulndb/import_test.go:88: CVE in current state but not in new state: ECHO-f04c-582a-df62 |
| 108 | + /Users/timbastin/Desktop/l3montree/devguard/vulndb/import_test.go:88: CVE in current state but not in new state: ECHO-1dc5-af13-00c1 |
| 109 | + /Users/timbastin/Desktop/l3montree/devguard/vulndb/import_test.go:88: CVE in current state but not in new state: ECHO-7627-a361-b4d3 |
| 110 | + /Users/timbastin/Desktop/l3montree/devguard/vulndb/import_test.go:88: CVE in current state but not in new state: ECHO-5818-1fba-950a |
| 111 | + /Users/timbastin/Desktop/l3montree/devguard/vulndb/import_test.go:88: CVE in current state but not in new state: ECHO-de02-7575-4370 |
| 112 | + /Users/timbastin/Desktop/l3montree/devguard/vulndb/import_test.go:88: CVE in current state but not in new state: ECHO-37cc-2ae7-e3c8 |
| 113 | + /Users/timbastin/Desktop/l3montree/devguard/vulndb/import_test.go:88: CVE in current state but not in new state: ECHO-34c7-ca18-1a8c |
| 114 | + /Users/timbastin/Desktop/l3montree/devguard/vulndb/import_test.go:88: CVE in current state but not in new state: ECHO-435f-9eb9-99cb |
| 115 | + /Users/timbastin/Desktop/l3montree/devguard/vulndb/import_test.go:88: CVE in current state but not in new state: ECHO-f4ca-f938-4210 |
| 116 | + /Users/timbastin/Desktop/l3montree/devguard/vulndb/import_test.go:88: CVE in current state but not in new state: ECHO-7f2f-e83a-5508 |
| 117 | + /Users/timbastin/Desktop/l3montree/devguard/vulndb/import_test.go:88: CVE in current state but not in new state: ECHO-879a-fe35-cf61 |
| 118 | + /Users/timbastin/Desktop/l3montree/devguard/vulndb/import_test.go:88: CVE in current state but not in new state: ECHO-c9a3-95ec-f0d8 |
| 119 | + /Users/timbastin/Desktop/l3montree/devguard/vulndb/import_test.go:88: CVE in current state but not in new state: |
| 120 | +*/ |
| 121 | + |
| 122 | +func TestWouldBeDeleted(t *testing.T) { |
| 123 | + b, err := os.ReadFile("test.osv.json") |
| 124 | + if err != nil { |
| 125 | + t.Fatalf("could not read test osv file: %v", err) |
| 126 | + } |
| 127 | + |
| 128 | + // parse as osv entry |
| 129 | + var entry dtos.OSV |
| 130 | + if err := json.Unmarshal(b, &entry); err != nil { |
| 131 | + t.Fatalf("could not parse test osv file: %v", err) |
| 132 | + } |
| 133 | + |
| 134 | + relationships := transformer.OSVToCVERelationships(&entry) |
| 135 | + affectedComponentsForCVE := transformer.AffectedComponentsFromOSV(&entry) |
| 136 | + if len(affectedComponentsForCVE) == 0 && len(relationships) == 0 { |
| 137 | + t.Logf("no relationships or affected components for CVE %s", entry.ID) |
| 138 | + } |
| 139 | + |
| 140 | + cve := transformer.OSVToCVE(&entry) |
| 141 | + if cve.CVE == "" { |
| 142 | + t.Logf("could not transform OSV to CVE: %s", entry.ID) |
| 143 | + } |
| 144 | +} |
0 commit comments