mirror of
https://github.com/0xMarcio/cve.git
synced 2026-10-23 16:35:19 +00:00
Fix release edge cases and published link consistency
This commit is contained in:
1 parent
73ec3df957
commit
65b97ae0d8
9 files changed
+281
-19
No files matched your search
@@ -0,0 +1,38 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
from unittest.mock import patch
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / 'scripts'))
|
||||
import build_pages
|
||||
import build_site
|
||||
|
||||
|
||||
class AdvisoryExclusionTests(unittest.TestCase):
|
||||
def test_explicit_wrong_cve_pair_is_removed_from_metadata_and_detail_only(self):
|
||||
wrong, correct = 'CVE-2024-23749', 'CVE-2024-25004'
|
||||
url = 'http://seclists.org/fulldisclosure/2024/Feb/14'
|
||||
ordinary = 'https://vendor.example/security/advisory'
|
||||
rows = [[url, ['Third Party Advisory', 'Exploit']], [ordinary, ['Vendor Advisory']]]
|
||||
raw = {cve: {'advisories': rows} for cve in (wrong, correct)}
|
||||
entries = [{'cve': cve, 'poc': []} for cve in (wrong, correct)]
|
||||
with patch.object(build_site, 'load_metadata', return_value=raw):
|
||||
metadata = build_site.build_metadata(entries)
|
||||
self.assertEqual(metadata[wrong]['advisories'], [rows[1]])
|
||||
self.assertEqual(metadata[correct]['advisories'], rows)
|
||||
self.assertFalse(build_site.reference_is_verified_poc(wrong, ordinary, raw, set()))
|
||||
self.assertTrue(build_site.reference_is_verified_poc(correct, url, raw, {(correct, url)}))
|
||||
self.assertFalse(build_site.reference_is_verified_poc(wrong, url, raw, {(wrong, url)}))
|
||||
data = {'cves': entries, 'meta': metadata, 'epss': {}, 'kev': {}, 'nuclei': {},
|
||||
'repo_meta': {}, 'related': {}, 'lastmod': {cve: '2026-10-07' for cve in (wrong, correct)}}
|
||||
wrong_page, correct_page = [build_pages.page(entry, data) for entry in entries]
|
||||
self.assertNotIn(f'href="{url}"', wrong_page)
|
||||
self.assertIn(f'href="{url}"', correct_page)
|
||||
for markup in (wrong_page, correct_page):
|
||||
self.assertIn(f'href="{ordinary}"', markup)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -0,0 +1,54 @@
|
||||
import hashlib
|
||||
import json
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
from unittest.mock import patch
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "scripts"))
|
||||
import build_pages
|
||||
|
||||
|
||||
class AssetVersionTests(unittest.TestCase):
|
||||
def tearDown(self):
|
||||
build_pages.asset_url.cache_clear()
|
||||
|
||||
def test_asset_urls_follow_bytes_without_changing_page_dates(self):
|
||||
entry = {"cve": "CVE-2024-1234", "desc": "Widget flaw", "modified": "2024-01-01",
|
||||
"poc": ["https://example.org/poc"]}
|
||||
payloads = {"CVE_list.json": [entry], "cve_metadata.json": {}, "epss.json": {},
|
||||
"kev.json": {}, "nuclei.json": {}, "repo_meta.json": {},
|
||||
"trending_poc.json": {"with_pocs": 1, "total_cves": 1,
|
||||
"generated": "2026-10-07T00:00:00Z", "landed": []}}
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
root = Path(directory)
|
||||
for name, body in (("style.css", b"body { color: black; }"), ("logic.js", b"const version = 1;")):
|
||||
(root / name).write_bytes(body)
|
||||
with patch.object(build_pages, "DOCS", directory), \
|
||||
patch.object(build_pages, "load", side_effect=payloads.__getitem__), \
|
||||
patch.object(build_pages, "previous_page_state", return_value={}) as previous:
|
||||
build_pages.main()
|
||||
state = (root / build_pages.PAGE_STATE).read_bytes()
|
||||
dates = (root / build_pages.LASTMOD).read_bytes()
|
||||
first = (root / "index.html").read_text()
|
||||
css = "/style.css?v=" + hashlib.sha256((root / "style.css").read_bytes()).hexdigest()[:16]
|
||||
js = "/logic.js?v=" + hashlib.sha256((root / "logic.js").read_bytes()).hexdigest()[:16]
|
||||
for name in ("index.html", "404.html", "CVE-2024-1234.html", "2024.html", "CVE-2024-1xxx.html"):
|
||||
self.assertIn(f'href="{css}"', (root / name).read_text(), name)
|
||||
self.assertIn(f'src="{js}"', first)
|
||||
self.assertIn(f'href="{build_pages.SITE}/CVE-2024-1234"', (root / "CVE-2024-1234.html").read_text())
|
||||
previous.return_value = json.loads(state)["pages"]
|
||||
for name in ("style.css", "logic.js"):
|
||||
with (root / name).open("ab") as handle:
|
||||
handle.write(b"\n/* new bundle */")
|
||||
build_pages.main()
|
||||
second = (root / "index.html").read_text()
|
||||
self.assertNotIn(css, second)
|
||||
self.assertNotIn(js, second)
|
||||
self.assertEqual((root / build_pages.PAGE_STATE).read_bytes(), state)
|
||||
self.assertEqual((root / build_pages.LASTMOD).read_bytes(), dates)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -84,6 +84,24 @@ class ReleaseLedgerTests(unittest.TestCase):
|
||||
self.assertEqual({k: v for k, v in row.items() if k != "checked"}, first)
|
||||
self.assertEqual(row["checked"], NOW)
|
||||
|
||||
def test_verified_introduction_after_first_observation_dates_pending_and_outdated_rows(self):
|
||||
old = {"created": "2026-09-20T00:00:00Z", "commit": "2026-09-21T00:00:00Z", "sha": "a" * 40,
|
||||
"commit_verified": True, "history_version": releases.HISTORY_VERSION - 1,
|
||||
"paths": ["exploit-CVE-2020-9999.py"], "rev": "b" * 64}
|
||||
for initial in (old, {"created": old["created"], "error": "No qualifying reproduction material"}):
|
||||
with self.subTest(initial=initial):
|
||||
ledger = releases.Ledger()
|
||||
releases.record(ledger, CVE, URL, initial, observed_at="2026-10-01T00:00:00Z")
|
||||
proof = {**old, "commit": "2026-10-05T00:00:00Z", "sha": "c" * 40,
|
||||
"history_version": releases.HISTORY_VERSION, "paths": [f"{CVE}.py"],
|
||||
"rev": "d" * 64, "pushed_at": "2026-10-05T01:00:00Z"}
|
||||
row = releases.record(ledger, CVE, URL, proof, observed_at=NOW)
|
||||
self.assertEqual((row["released"], row["basis"], row.get("history_version"), row["paths"]),
|
||||
(proof["commit"], "commit", releases.HISTORY_VERSION, proof["paths"]))
|
||||
self.assertEqual(row["seen"], "2026-10-01T00:00:00Z")
|
||||
self.assertNotIn("imported", row)
|
||||
self.assertEqual(len(releases.landed(ledger, now=NOW)), 1)
|
||||
|
||||
def test_unversioned_history_is_corrected_and_older_methods_cannot_restore_it(self):
|
||||
ledger = releases.Ledger()
|
||||
original = {"commit": "2020-01-01T00:00:00Z", "commit_verified": True,
|
||||
@@ -131,6 +149,14 @@ class ReleaseLedgerTests(unittest.TestCase):
|
||||
"seen": NOW, "pushed_at": "2026-10-07T11:00:00Z"}
|
||||
self.assertEqual(releases.date_release(evidence, now=NOW), (evidence["created"], "created"))
|
||||
|
||||
def test_first_observation_still_caps_non_commit_dates_and_absence(self):
|
||||
for field in ("created", "public", "source"):
|
||||
evidence = {field: "2026-10-05T00:00:00Z", "seen": "2026-10-01T00:00:00Z", "pushed_at": NOW}
|
||||
self.assertEqual(releases.date_release(evidence, now=NOW), (None, "unknown"))
|
||||
evidence = {"seen": "2026-10-01T00:00:00Z", "absent": "2026-10-02T00:00:00Z",
|
||||
"previous_head": "a" * 40, "absence_verified": True}
|
||||
self.assertEqual(releases.date_release(evidence, now=NOW), (None, "unknown"))
|
||||
|
||||
def test_imported_history_uses_repository_creation_lower_bound(self):
|
||||
self.assertEqual(releases.date_release({"created": "2026-10-06T00:00:00Z",
|
||||
"commit": "2023-01-01T00:00:00Z", "commit_verified": True}, now=NOW),
|
||||
@@ -248,6 +274,22 @@ class ReleaseLedgerTests(unittest.TestCase):
|
||||
self.assertTrue(all(row.get("bulk") for row in ledger.values()))
|
||||
self.assertEqual(releases.landed(ledger, now=NOW), [])
|
||||
|
||||
def test_absence_dated_batch_counts_pending_paths_alongside_distinct_commits(self):
|
||||
for resolved in (30, 8):
|
||||
with self.subTest(resolved=resolved):
|
||||
ledger = releases.Ledger()
|
||||
for offset in range(30):
|
||||
cve = f"CVE-2026-{20000 + offset}"
|
||||
url = f"https://github.com/zan8in/afrog/blob/main/pocs/{cve}.yaml"
|
||||
evidence = {"repo": 7, "created": "2020-01-01T00:00:00Z", "pushed_at": NOW,
|
||||
"commit": "2026-09-01T00:00:00Z", "sha": f"{offset:040x}", "commit_verified": True,
|
||||
"history_version": releases.HISTORY_VERSION, "previous_head": "a" * 40,
|
||||
"absent": "2026-10-06T00:00:00Z", "absence_verified": True}
|
||||
releases.record(ledger, cve, url, evidence if offset < resolved else {"error": "Deferred"}, observed_at=NOW)
|
||||
releases.mark_bulk(ledger)
|
||||
self.assertEqual(releases.landed(ledger, now=NOW), [])
|
||||
self.assertEqual(sum(bool(row.get("bulk")) for row in ledger.values()), resolved)
|
||||
|
||||
def test_shards_are_monotonic_immutable_and_idempotent(self):
|
||||
with tempfile.TemporaryDirectory() as temporary:
|
||||
directory = Path(temporary)
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import importlib.util
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
from unittest.mock import patch
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
sys.path.insert(0, str(ROOT / 'scripts'))
|
||||
import build_site
|
||||
import source_artifacts
|
||||
|
||||
SPEC = importlib.util.spec_from_file_location('reviewed_trending', ROOT / '.github/getTrending.py')
|
||||
trending = importlib.util.module_from_spec(SPEC)
|
||||
SPEC.loader.exec_module(trending)
|
||||
|
||||
|
||||
class ReviewedPublicationTests(unittest.TestCase):
|
||||
def test_reviewed_pinned_artifact_wins_over_existing_repository_root(self):
|
||||
row = source_artifacts.load_reviews()[0]
|
||||
artifact = source_artifacts.ArtifactEvidence(row['cve'], row['repository'], row['path'],
|
||||
row['revision'], row['sha256'], row['id'])
|
||||
root = f"https://github.com/{row['repository']}"
|
||||
for links in ([root, artifact.url], [artifact.url, root]):
|
||||
self.assertEqual(build_site.dedupe_source_links(links, row['cve']), [artifact.url])
|
||||
unrelated = root + '/blob/main/unreviewed.py'
|
||||
self.assertEqual(build_site.dedupe_source_links([root, unrelated], row['cve']), [root])
|
||||
|
||||
def test_multiple_reviewed_paths_use_the_same_publication_choice(self):
|
||||
cve, name = 'CVE-2024-1234', 'researcher/CVE-2024-1234-lab'
|
||||
evidence = [source_artifacts.ArtifactEvidence(cve, name, path, 'a' * 40, 'b' * 64, 'test')
|
||||
for path in ['expl/longer.py', 'expl/a.py']]
|
||||
row = {'name': name.split('/')[1], 'full_name': name, 'html_url': f'https://github.com/{name}'}
|
||||
content = {'root': {'entries': [{'name': 'expl', 'type': 'tree'}]},
|
||||
'readmeMd': {'text': f'PoC for {cve}'}, 'defaultBranchRef': {'target': {'oid': 'a' * 40}}}
|
||||
def attach(repo, *args, **kwargs):
|
||||
repo['_source_artifacts'] = tuple(evidence)
|
||||
with patch.object(trending, 'graphql', return_value={'r0': content}), \
|
||||
patch.object(trending, 'load_blacklist', return_value=[]), \
|
||||
patch.object(trending, 'attach_source_artifacts', side_effect=attach), \
|
||||
patch.object(build_site, 'reviewed_artifact_keys', return_value={cve: {build_site.link_key(a.url) for a in evidence}}):
|
||||
accepted, paths = trending.qualifying_repositories([row], '')
|
||||
published = build_site.dedupe_source_links([row['html_url'], *[a.url for a in evidence]], cve)
|
||||
self.assertEqual(len(accepted), 1)
|
||||
self.assertEqual(accepted[0]['_artifact_url'], published[0])
|
||||
self.assertEqual(published, [evidence[1].url])
|
||||
self.assertEqual(set(paths[name]), {a.path for a in evidence})
|
||||
|
||||
def test_landed_merge_rejects_a_link_that_publication_dedupes_away(self):
|
||||
cve = 'CVE-2024-1234'
|
||||
root = f'https://github.com/unknown/{cve}'
|
||||
payload = root + '/blob/main/exploit.py'
|
||||
candidate = {'cve': cve, 'html_url': root, '_artifact_url': payload, '_released': '2026-10-07T00:00:00Z'}
|
||||
with tempfile.TemporaryDirectory() as temp:
|
||||
metadata = Path(temp) / 'metadata.json'
|
||||
metadata.write_text('{}')
|
||||
with patch.object(build_site, 'REPO_META', metadata), \
|
||||
patch.object(build_site, 'build_cve_list', return_value=([{'cve': cve, 'poc': [root]}], 1)), \
|
||||
patch.object(trending, 'known_exploited', return_value=set()):
|
||||
self.assertEqual(trending.ledger_landed({}, [candidate]), [])
|
||||
|
||||
def test_landed_merge_keeps_reviewed_payload_that_will_replace_root(self):
|
||||
row = source_artifacts.load_reviews()[0]
|
||||
artifact = source_artifacts.ArtifactEvidence(row['cve'], row['repository'], row['path'],
|
||||
row['revision'], row['sha256'], row['id'])
|
||||
root = f"https://github.com/{row['repository']}"
|
||||
candidate = {'cve': row['cve'], 'html_url': root, '_artifact_url': artifact.url,
|
||||
'_released': '2026-10-07T00:00:00Z'}
|
||||
with tempfile.TemporaryDirectory() as temp:
|
||||
metadata = Path(temp) / 'metadata.json'
|
||||
metadata.write_text('{}')
|
||||
with patch.object(build_site, 'REPO_META', metadata), \
|
||||
patch.object(build_site, 'build_cve_list', return_value=([{'cve': row['cve'], 'poc': [root]}], 1)), \
|
||||
patch.object(trending, 'known_exploited', return_value=set()):
|
||||
self.assertEqual(trending.ledger_landed({}, [candidate]), [candidate])
|
||||
|
||||
def test_curated_variants_keep_independent_paths(self):
|
||||
urls = [f'https://github.com/google/security-research/blob/master/pocs/CVE-2024-1234/variant-{n}.c'
|
||||
for n in range(116)]
|
||||
self.assertEqual(build_site.dedupe_source_links(urls, 'CVE-2024-1234', preserve_paths=True), urls)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user