Skip to content

Commit 555462c

Browse files
committed
Harden dependency resolution, npm audit edge cases, and reconciliation
Make arbitrary-ref dependency probing more tolerant of parser shape errors and mark curated scans as incomplete when curated dependencies fail to resolve. Tighten npm audit handling by: - recording discovery failures and empty installed bundle trees as incomplete - generating prod-only lockfiles with --package-lock-only when no lockfile is present - retrying ENOLOCK recovery even when node_modules exists without a lockfile - handling boolean bundleDependencies and avoiding duplicate installed-tree walks - skipping invalid GitHub advisory specifiers or versions per advisory while marking the scan incomplete - making per-package GitHub advisory query failures non-fatal - normalizing npm advisory IDs across modern and legacy audit payloads - preferring CVE identifiers when GitHub exposes them Preserve reconciliation when a vendored npm advisory changes from GHSA to CVE by carrying alternate advisory identifiers in the scan payload and matching existing issues through those aliases before create/close decisions.
1 parent 7852610 commit 555462c

4 files changed

Lines changed: 1034 additions & 207 deletions

File tree

dep_checker/main.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class Vulnerability:
3535
def __init__(self, id: str, url: str, dependency: str, version: str, source: str = "binary",
3636
severity: Optional[str] = None, via: Optional[list] = None,
3737
fix_available: Optional[bool] = None, main_dep_name: Optional[str] = None,
38-
main_dep_path: Optional[str] = None):
38+
main_dep_path: Optional[str] = None, advisory_aliases: Optional[list[str]] = None):
3939
self.id = id
4040
self.url = url
4141
self.dependency = dependency
@@ -46,6 +46,7 @@ def __init__(self, id: str, url: str, dependency: str, version: str, source: str
4646
self.fix_available = fix_available # whether fix is available
4747
self.main_dep_name = main_dep_name # main dependency name for npm vulnerabilities
4848
self.main_dep_path = main_dep_path # path to the main dependency
49+
self.advisory_aliases = advisory_aliases or [] # alternate IDs for reconciliation migration
4950

5051

5152
class VulnerabilityEncoder(json.JSONEncoder):
@@ -69,6 +70,8 @@ def default(self, obj):
6970
result["main_dep_path"] = obj.main_dep_path
7071
if obj.fix_available is not None:
7172
result["fix_available"] = obj.fix_available
73+
if obj.advisory_aliases:
74+
result["advisory_aliases"] = obj.advisory_aliases
7275
return result
7376
# Let the base class default method raise the TypeError
7477
return json.JSONEncoder.default(self, obj)
@@ -395,7 +398,7 @@ def main() -> int:
395398

396399
from npm_audit import NPMAuditChecker
397400
print("Running npm package vulnerability audit...", file=sys.stderr)
398-
npm_checker = NPMAuditChecker(repo_path, npm_timeout)
401+
npm_checker = NPMAuditChecker(repo_path, npm_timeout, gh_token=gh_token)
399402
npm_vulnerabilities = npm_checker.check_npm_vulnerabilities(Vulnerability)
400403
if npm_checker.failed_packages:
401404
scan_complete = False

0 commit comments

Comments
 (0)