Skip to content

Commit 125f78d

Browse files
committed
fixup
1 parent e8ef844 commit 125f78d

2 files changed

Lines changed: 50 additions & 25 deletions

File tree

dep_checker/npm_audit.py

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -332,8 +332,7 @@ def merge_vulnerability(vuln) -> None:
332332
return
333333
vulnerabilities_by_id[vuln.id] = vuln
334334

335-
packages_needing_repo_fallback: list[Dict[str, str]] = []
336-
packages_with_cve_match: set[tuple[str, str]] = set()
335+
packages_for_repo_advisories = list(packages)
337336
if self.gh_token is not None:
338337
transport = AIOHTTPTransport(
339338
url="https://api.github.com/graphql",
@@ -347,8 +346,6 @@ def merge_vulnerability(vuln) -> None:
347346
)
348347

349348
for package in packages:
350-
matched_this_package = False
351-
has_cve_match = False
352349
try:
353350
result = client.execute(
354351
github_vulnerabilities_query,
@@ -358,7 +355,6 @@ def merge_vulnerability(vuln) -> None:
358355
logger.warning(
359356
f"Skipping GitHub advisory query for {package['name']}@{package['version']}: {exc}"
360357
)
361-
packages_needing_repo_fallback.append(package)
362358
continue
363359
for vuln in result["securityVulnerabilities"]["nodes"]:
364360
if vuln["advisory"]["withdrawnAt"] is not None:
@@ -375,11 +371,7 @@ def merge_vulnerability(vuln) -> None:
375371
f"Skipping advisory match for {package['name']}@{package['version']}: {exc}"
376372
)
377373
continue
378-
matched_this_package = True
379374
preferred_id = self.preferred_advisory_id(vuln["advisory"])
380-
if preferred_id.startswith("CVE-"):
381-
has_cve_match = True
382-
packages_with_cve_match.add((package["name"], package["version"]))
383375
merge_vulnerability(
384376
vulnerability_class(
385377
id=preferred_id,
@@ -395,12 +387,7 @@ def merge_vulnerability(vuln) -> None:
395387
advisory_aliases=self.advisory_aliases(vuln["advisory"], preferred_id),
396388
)
397389
)
398-
if not matched_this_package or not has_cve_match:
399-
packages_needing_repo_fallback.append(package)
400-
else:
401-
packages_needing_repo_fallback = list(packages)
402-
403-
for package in packages_needing_repo_fallback:
390+
for package in packages_for_repo_advisories:
404391
try:
405392
for vuln in self.query_repository_advisory_vulnerabilities(package_dir, package):
406393
merge_vulnerability(

dep_checker/test_npm_audit.py

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -373,10 +373,30 @@ def execute(self, query, variable_values):
373373
npm_audit.searchCVE = original_search
374374

375375

376-
def test_repository_advisory_fallback_discovers_package_cve() -> None:
376+
def test_repository_advisories_are_merged_with_ghad_results() -> None:
377377
class FakeClient:
378378
def execute(self, query, variable_values):
379-
return {"securityVulnerabilities": {"nodes": []}}
379+
return {
380+
"securityVulnerabilities": {
381+
"nodes": [
382+
{
383+
"severity": "MODERATE",
384+
"vulnerableVersionRange": ">=10.1.1, <=10.2.0",
385+
"firstPatchedVersion": {"identifier": "10.2.1"},
386+
"advisory": {
387+
"ghsaId": "GHSA-22jq-vg5j-6vgg",
388+
"identifiers": [
389+
{"type": "GHSA", "value": "GHSA-22jq-vg5j-6vgg"},
390+
{"type": "CVE", "value": "CVE-2026-54272"},
391+
],
392+
"permalink": "https://github.com/advisories/GHSA-22jq-vg5j-6vgg",
393+
"summary": "ip-address mapped/NAT64 bypass",
394+
"withdrawnAt": None,
395+
},
396+
}
397+
]
398+
}
399+
}
380400

381401
class FakeResponse:
382402
def __enter__(self):
@@ -387,12 +407,32 @@ def __exit__(self, exc_type, exc, tb):
387407

388408
def read(self):
389409
return json.dumps([
410+
{
411+
"ghsa_id": "GHSA-mwp4-54f8-5fhr",
412+
"cve_id": "CVE-2026-69192",
413+
"html_url": "https://github.com/beaugunderson/ip-address/security/advisories/GHSA-mwp4-54f8-5fhr",
414+
"severity": "high",
415+
"summary": "ip-address leading-zero octet parsing bypass",
416+
"state": "published",
417+
"withdrawn_at": None,
418+
"identifiers": [
419+
{"type": "GHSA", "value": "GHSA-mwp4-54f8-5fhr"},
420+
{"type": "CVE", "value": "CVE-2026-69192"},
421+
],
422+
"vulnerabilities": [
423+
{
424+
"package": {"ecosystem": "npm", "name": "ip-address"},
425+
"vulnerable_version_range": "<=10.3.0",
426+
"patched_versions": "10.3.1",
427+
}
428+
],
429+
},
390430
{
391431
"ghsa_id": "GHSA-4xrf-jv44-h6hh",
392432
"cve_id": "CVE-2026-69198",
393433
"html_url": "https://github.com/beaugunderson/ip-address/security/advisories/GHSA-4xrf-jv44-h6hh",
394434
"severity": "medium",
395-
"summary": "ip-address SSRF classification bypass",
435+
"summary": "ip-address CIDR suffix bypass",
396436
"state": "published",
397437
"withdrawn_at": None,
398438
"identifiers": [
@@ -402,11 +442,11 @@ def read(self):
402442
"vulnerabilities": [
403443
{
404444
"package": {"ecosystem": "npm", "name": "ip-address"},
405-
"vulnerable_version_range": ">=10.1.1, <10.2.2",
445+
"vulnerable_version_range": ">=10.1.1, <=10.2.1",
406446
"patched_versions": "10.2.2",
407447
}
408448
],
409-
}
449+
},
410450
]).encode()
411451

412452
original_client = npm_audit.Client
@@ -430,10 +470,8 @@ def read(self):
430470
[{"name": "ip-address", "version": "10.2.0", "path": "node_modules/ip-address"}],
431471
Vulnerability,
432472
)
433-
assert len(vulns) == 1, vulns
434-
assert vulns[0].id == "CVE-2026-69198"
435-
assert vulns[0].advisory_aliases == ["GHSA-4xrf-jv44-h6hh"]
436-
assert vulns[0].url == "https://github.com/beaugunderson/ip-address/security/advisories/GHSA-4xrf-jv44-h6hh"
473+
ids = sorted(v.id for v in vulns)
474+
assert ids == ["CVE-2026-54272", "CVE-2026-69192", "CVE-2026-69198"], vulns
437475
finally:
438476
npm_audit.Client = original_client
439477
npm_audit.AIOHTTPTransport = original_transport
@@ -707,7 +745,7 @@ def test_npm_audit_basic() -> None:
707745
test_enolock_with_node_modules_still_falls_back()
708746
test_enolock_falls_back_to_install_and_normal_audit()
709747
test_nvd_primary_merges_ghad_aliases()
710-
test_repository_advisory_fallback_discovers_package_cve()
748+
test_repository_advisories_are_merged_with_ghad_results()
711749
test_query_failure_is_skipped_per_package()
712750
test_invalid_advisory_range_or_version_is_skipped()
713751
test_normalize_npm_advisory_id()

0 commit comments

Comments
 (0)