2727logger = logging .getLogger (__name__ )
2828
2929GITHUB_API_VERSION = "2026-03-10"
30+ TRACE_PACKAGES = {"ip-address" }
3031
3132
3233class AuditParseError (Exception ):
@@ -310,7 +311,16 @@ def walk(name: str, node: Dict, path_parts: Optional[list[str]] = None) -> None:
310311 if name in roots and isinstance (node , dict ):
311312 walk (name , node , [])
312313
313- return list (seen .values ())
314+ packages = list (seen .values ())
315+ logger .info (
316+ f"Collected { len (packages )} installed bundled npm packages from { package_dir } (roots={ len (roots )} )"
317+ )
318+ for traced in packages :
319+ if traced ["name" ] in TRACE_PACKAGES :
320+ logger .info (
321+ f"Trace package present in installed npm tree: { traced ['name' ]} @{ traced ['version' ]} path={ traced ['path' ]} "
322+ )
323+ return packages
314324
315325 def query_installed_package_vulnerabilities (
316326 self , package_dir : Path , packages : List [Dict [str , str ]], vulnerability_class
@@ -334,6 +344,14 @@ def merge_vulnerability(vuln) -> None:
334344 vulnerabilities_by_id [vuln .id ] = vuln
335345
336346 packages_for_global_advisories = list (packages )
347+ logger .info (
348+ f"Querying npm advisories for { len (packages_for_global_advisories )} installed packages from { package_dir } "
349+ )
350+ for traced in packages_for_global_advisories :
351+ if traced ["name" ] in TRACE_PACKAGES :
352+ logger .info (
353+ f"Trace package entering advisory queries: { traced ['name' ]} @{ traced ['version' ]} path={ traced .get ('path' , '<unknown>' )} "
354+ )
337355 if self .gh_token is not None :
338356 transport = AIOHTTPTransport (
339357 url = "https://api.github.com/graphql" ,
@@ -357,6 +375,10 @@ def merge_vulnerability(vuln) -> None:
357375 f"Skipping GitHub advisory query for { package ['name' ]} @{ package ['version' ]} : { exc } "
358376 )
359377 continue
378+ if package ["name" ] in TRACE_PACKAGES :
379+ logger .info (
380+ f"Trace package GHAD results for { package ['name' ]} @{ package ['version' ]} : { len (result ['securityVulnerabilities' ]['nodes' ])} candidates"
381+ )
360382 for vuln in result ["securityVulnerabilities" ]["nodes" ]:
361383 if vuln ["advisory" ]["withdrawnAt" ] is not None :
362384 continue
@@ -373,6 +395,10 @@ def merge_vulnerability(vuln) -> None:
373395 )
374396 continue
375397 preferred_id = self .preferred_advisory_id (vuln ["advisory" ])
398+ if package ["name" ] in TRACE_PACKAGES :
399+ logger .info (
400+ f"Trace package GHAD match: { package ['name' ]} @{ package ['version' ]} matched { preferred_id } range={ vuln ['vulnerableVersionRange' ]} "
401+ )
376402 merge_vulnerability (
377403 vulnerability_class (
378404 id = preferred_id ,
@@ -390,6 +416,9 @@ def merge_vulnerability(vuln) -> None:
390416 )
391417 try :
392418 global_advisories = self .fetch_global_advisories (packages_for_global_advisories )
419+ logger .info (
420+ f"Fetched { len (global_advisories )} global advisories for { len (packages_for_global_advisories )} installed packages from { package_dir } "
421+ )
393422 except Exception as exc :
394423 self .failed_packages .append (
395424 f"{ package_dir } : global advisory query failed: { exc } "
@@ -398,7 +427,12 @@ def merge_vulnerability(vuln) -> None:
398427 global_advisories = []
399428
400429 for package in packages_for_global_advisories :
401- for vuln in self .match_global_advisories (package , global_advisories ):
430+ matched_global = self .match_global_advisories (package , global_advisories )
431+ if package ["name" ] in TRACE_PACKAGES :
432+ logger .info (
433+ f"Trace package global advisory matches for { package ['name' ]} @{ package ['version' ]} : { len (matched_global )} "
434+ )
435+ for vuln in matched_global :
402436 merge_vulnerability (
403437 vulnerability_class (
404438 id = vuln ["id" ],
@@ -460,6 +494,10 @@ def merge_vulnerability(vuln) -> None:
460494 def match_global_advisories (self , package : Dict [str , str ], advisories : List [Dict ]) -> List [Dict [str , object ]]:
461495 results : List [Dict [str , object ]] = []
462496 seen_ids : set [str ] = set ()
497+ if package ["name" ] in TRACE_PACKAGES :
498+ logger .info (
499+ f"Trace package evaluating { len (advisories )} global advisories for { package ['name' ]} @{ package ['version' ]} "
500+ )
463501 for advisory in advisories :
464502 if advisory .get ("withdrawn_at" ) is not None :
465503 continue
@@ -473,9 +511,18 @@ def match_global_advisories(self, package: Dict[str, str], advisories: List[Dict
473511 continue
474512 try :
475513 vulnerable_range = self .normalize_version_range (vuln .get ("vulnerable_version_range" ) or "" )
476- if not vulnerable_range or not SpecifierSet (vulnerable_range ).contains (package ["version" ], prereleases = True ):
514+ matched = bool (vulnerable_range ) and SpecifierSet (vulnerable_range ).contains (package ["version" ], prereleases = True )
515+ if package ["name" ] in TRACE_PACKAGES :
516+ logger .info (
517+ f"Trace package global advisory candidate: { package ['name' ]} @{ package ['version' ]} advisory={ preferred_id } range={ vuln .get ('vulnerable_version_range' )} normalized={ vulnerable_range !r} matched={ matched } "
518+ )
519+ if not matched :
477520 continue
478- except (InvalidSpecifier , InvalidVersion ):
521+ except (InvalidSpecifier , InvalidVersion ) as exc :
522+ if package ["name" ] in TRACE_PACKAGES :
523+ logger .warning (
524+ f"Trace package global advisory parse failure for { package ['name' ]} @{ package ['version' ]} advisory={ preferred_id } : { exc } "
525+ )
479526 continue
480527 seen_ids .add (preferred_id )
481528 results .append ({
@@ -509,6 +556,12 @@ def fetch_global_advisories(self, packages: List[Dict[str, str]]) -> List[Dict]:
509556
510557 for index in range (0 , len (requested ), batch_size ):
511558 batch = requested [index :index + batch_size ]
559+ logger .info (
560+ f"Fetching global advisories batch { index // batch_size + 1 } of { ((len (requested ) - 1 ) // batch_size ) + 1 } with { len (batch )} packages"
561+ )
562+ traced_batch = [item for item in batch if item .split ('@' , 1 )[0 ] in TRACE_PACKAGES ]
563+ if traced_batch :
564+ logger .info (f"Trace package present in global advisory batch: { traced_batch } " )
512565 query = urllib .parse .urlencode (
513566 [("ecosystem" , "npm" ), * ( ("affects[]" , item ) for item in batch ), ("per_page" , "100" )]
514567 )
@@ -521,6 +574,15 @@ def fetch_global_advisories(self, packages: List[Dict[str, str]]) -> List[Dict]:
521574 f"Global advisory query returned non-list payload for batch { index // batch_size + 1 } of { ((len (requested ) - 1 ) // batch_size ) + 1 } : { payload } "
522575 )
523576 continue
577+ logger .info (
578+ f"Global advisory query returned { len (payload )} advisory records for batch { index // batch_size + 1 } "
579+ )
580+ if traced_batch :
581+ for item in payload :
582+ if isinstance (item , dict ):
583+ logger .info (
584+ f"Trace package batch advisory seen: ghsa={ item .get ('ghsa_id' )} cve={ item .get ('cve_id' )} summary={ item .get ('summary' , '' )[:120 ]} "
585+ )
524586 for item in payload :
525587 if not isinstance (item , dict ):
526588 continue
0 commit comments