|
1 | 1 | import importlib.util |
2 | 2 | import json |
3 | 3 | from copy import deepcopy |
| 4 | +from datetime import date, timedelta |
4 | 5 | import unittest |
5 | 6 | from pathlib import Path |
6 | 7 | spec = importlib.util.spec_from_file_location("gate", Path(__file__).with_name("enforce-builder-vulnerabilities.py")) |
@@ -93,6 +94,56 @@ def test_refreshed_review_fixed_or_package_drift_rejected(self): |
93 | 94 | self.headers = deepcopy(original) |
94 | 95 | self.headers["mediumRefresh"]["entries"][0][key] = value |
95 | 96 | with self.subTest(key=key), self.assertRaises(ValueError): self.check() |
| 97 | + def tracked_medium_headers(self): |
| 98 | + root = Path(__file__).resolve().parents[1] |
| 99 | + self.ledger = json.loads((root / "dapper-unfixed.json").read_text()) |
| 100 | + self.headers = json.loads((root / "dapper-headers.json").read_text()) |
| 101 | + return [entry for entry in self.ledger["unfixed"] |
| 102 | + if entry.get("scanRawSha256") == "e42870cc26d1fe7a9e6f212a13e38681db5d3227a6ec01a9188a4c69e5a95f4a"] |
| 103 | + def test_tracked_99_medium_headers_have_pinned_no_fix_evidence(self): |
| 104 | + entries = self.tracked_medium_headers() |
| 105 | + self.assertEqual(len(entries), 99) |
| 106 | + self.assertEqual(len({entry["id"] for entry in entries}), 99) |
| 107 | + snapshot = "8fdde882b47cb3972740ffef118fe74c628e993c" |
| 108 | + for entry in entries: |
| 109 | + with self.subTest(id=entry["id"]): |
| 110 | + self.assertNotIn(entry["id"], self.headers["ids"]) |
| 111 | + self.assertEqual((entry["package"], entry["version"], entry["purl"], entry["severity"], entry["status"]), |
| 112 | + ("linux-libc-dev", gate.HEADER_VERSION, gate.HEADER_PURL, "MEDIUM", "no_official_fix")) |
| 113 | + self.assertEqual(entry["officialSnapshot"], snapshot) |
| 114 | + self.assertEqual(entry["officialEvidence"], "https://raw.githubusercontent.com/canonical/ubuntu-security-notices/" |
| 115 | + + snapshot + "/osv/cve/2026/UBUNTU-" + entry["id"] + ".json") |
| 116 | + self.assertRegex(entry["officialRawSha256"], r"^[0-9a-f]{64}$") |
| 117 | + self.assertTrue(entry["officialModified"]) |
| 118 | + self.assertEqual(entry["officialPriority"], ["medium"]) |
| 119 | + self.assertEqual(entry["officialRangeEvents"], [{"introduced": "0"}]) |
| 120 | + self.assertEqual(entry["officialFixedVersions"], []) |
| 121 | + self.assertEqual(entry["checkedAt"], "2026-11-02") |
| 122 | + self.assertEqual(date.fromisoformat(entry["reviewAfter"]) - date.fromisoformat(entry["checkedAt"]), |
| 123 | + timedelta(days=7)) |
| 124 | + self.assertEqual(entry["scanApplicableSha256"], "ab6de6f510e9f98640d3408e34acaa57cd668ce81e7f2898b07c4eac0a438240") |
| 125 | + self.assertEqual((entry["scanRunId"], entry["scanArtifactId"]), (41327670634, 13091519384)) |
| 126 | + self.assertEqual(entry["scanArtifactSha256"], "cb34b687d30a498064e8144fcc293944ce964e4c605da21cbe8ba34570706847") |
| 127 | + def test_tracked_99_exact_medium_headers(self): |
| 128 | + entries = self.tracked_medium_headers() |
| 129 | + self.report["Results"][0]["Vulnerabilities"] = [ |
| 130 | + {"VulnerabilityID": entry["id"], "PkgName": entry["package"], "InstalledVersion": entry["version"], |
| 131 | + "PkgIdentifier": {"PURL": entry["purl"]}, "Severity": entry["severity"], "FixedVersion": ""} |
| 132 | + for entry in entries] |
| 133 | + self.assertEqual(self.check(), []) |
| 134 | + def test_tracked_medium_headers_reject_fix_severity_or_identity_drift(self): |
| 135 | + entry = self.tracked_medium_headers()[0] |
| 136 | + baseline = {"VulnerabilityID": entry["id"], "PkgName": entry["package"], "InstalledVersion": entry["version"], |
| 137 | + "PkgIdentifier": {"PURL": entry["purl"]}, "Severity": "MEDIUM", "FixedVersion": ""} |
| 138 | + mutations = [("Severity", value) for value in ("LOW", "HIGH", "CRITICAL", "UNKNOWN")] |
| 139 | + mutations += [("FixedVersion", "7.0.0-42.42"), ("InstalledVersion", "7.0.0-42.42"), |
| 140 | + ("PkgIdentifier", {"PURL": gate.HEADER_PURL + "&changed=1"}), |
| 141 | + ("VulnerabilityID", "CVE-unreviewed"), ("PkgName", "linux-image-generic")] |
| 142 | + for key, value in mutations: |
| 143 | + finding = deepcopy(baseline) |
| 144 | + finding[key] = value |
| 145 | + self.report["Results"][0]["Vulnerabilities"] = [finding] |
| 146 | + with self.subTest(field=key, value=value): self.assertTrue(self.check()) |
96 | 147 | def test_header_version_or_purl_drift_rejected(self): |
97 | 148 | for field in ("InstalledVersion", "PkgIdentifier"): |
98 | 149 | f = self.header() |
|
0 commit comments