|
24 | 24 | from packaging.specifiers import SpecifierSet |
25 | 25 | from typing import Optional, List |
26 | 26 | from pathlib import Path |
| 27 | +from requests.exceptions import RequestException |
27 | 28 |
|
28 | 29 | import json |
29 | 30 | import logging |
| 31 | +import traceback |
| 32 | + |
| 33 | + |
| 34 | +EXIT_SUCCESS = 0 |
| 35 | +EXIT_VULNERABILITIES_FOUND = 1 |
| 36 | +EXIT_SCAN_ERROR = 2 |
30 | 37 |
|
31 | 38 |
|
32 | 39 | class Vulnerability: |
@@ -332,51 +339,58 @@ def main() -> int: |
332 | 339 | "Warning: NVD API key not provided, queries will be slower due to rate limiting" |
333 | 340 | ) |
334 | 341 |
|
335 | | - dependencies = resolve_dependencies(repo_path, repo_branch) |
336 | | - ghad_vulnerabilities: list[Vulnerability] = ( |
337 | | - list() if gh_token is None else query_ghad(dependencies, gh_token, repo_path) |
338 | | - ) |
339 | | - nvd_vulnerabilities: list[Vulnerability] = query_nvd( |
340 | | - dependencies, nvd_key, repo_path |
341 | | - ) |
| 342 | + try: |
| 343 | + dependencies = resolve_dependencies(repo_path, repo_branch) |
| 344 | + ghad_vulnerabilities: list[Vulnerability] = ( |
| 345 | + list() if gh_token is None else query_ghad(dependencies, gh_token, repo_path) |
| 346 | + ) |
| 347 | + nvd_vulnerabilities: list[Vulnerability] = query_nvd( |
| 348 | + dependencies, nvd_key, repo_path |
| 349 | + ) |
342 | 350 |
|
343 | | - # NPM package vulnerability checking |
344 | | - npm_vulnerabilities: list[Vulnerability] = [] |
345 | | - if include_npm: |
346 | | - try: |
347 | | - # Configure logging for npm audit |
348 | | - logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s') |
349 | | - |
350 | | - from npm_audit import NPMAuditChecker |
351 | | - print("Running npm package vulnerability audit...") |
352 | | - npm_checker = NPMAuditChecker(repo_path, npm_timeout) |
353 | | - npm_vulnerabilities = npm_checker.check_npm_vulnerabilities(Vulnerability) |
354 | | - print(f"Found {len(npm_vulnerabilities)} npm package vulnerabilities") |
355 | | - except ImportError as e: |
356 | | - print(f"Warning: npm_audit module not found, skipping npm vulnerability checking: {e}") |
357 | | - except Exception as e: |
358 | | - print(f"Warning: npm vulnerability checking failed: {e}") |
359 | | - import traceback |
360 | | - print(f"Traceback: {traceback.format_exc()}") |
361 | | - |
362 | | - all_vulnerabilities = { |
363 | | - "vulnerabilities": ghad_vulnerabilities + nvd_vulnerabilities + npm_vulnerabilities |
364 | | - } |
365 | | - no_vulnerabilities_found = not ghad_vulnerabilities and not nvd_vulnerabilities and not npm_vulnerabilities |
366 | | - if json_output: |
367 | | - print(json.dumps(all_vulnerabilities, cls=VulnerabilityEncoder)) |
368 | | - return 0 if no_vulnerabilities_found else 1 |
369 | | - elif no_vulnerabilities_found: |
370 | | - print(f"No new vulnerabilities found ({len(ignore_list)} ignored)") |
371 | | - return 0 |
372 | | - else: |
373 | | - print("WARNING: New vulnerabilities found") |
374 | | - for vuln in all_vulnerabilities["vulnerabilities"]: |
375 | | - print( |
376 | | - f"- {vuln.dependency} (version {vuln.version}) : {vuln.id} ({vuln.url})" |
377 | | - ) |
378 | | - print(f"\n{vulnerability_found_message}") |
379 | | - return 1 |
| 351 | + # NPM package vulnerability checking |
| 352 | + npm_vulnerabilities: list[Vulnerability] = [] |
| 353 | + if include_npm: |
| 354 | + try: |
| 355 | + # Configure logging for npm audit |
| 356 | + logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s') |
| 357 | + |
| 358 | + from npm_audit import NPMAuditChecker |
| 359 | + print("Running npm package vulnerability audit...") |
| 360 | + npm_checker = NPMAuditChecker(repo_path, npm_timeout) |
| 361 | + npm_vulnerabilities = npm_checker.check_npm_vulnerabilities(Vulnerability) |
| 362 | + print(f"Found {len(npm_vulnerabilities)} npm package vulnerabilities") |
| 363 | + except ImportError as e: |
| 364 | + print(f"Warning: npm_audit module not found, skipping npm vulnerability checking: {e}") |
| 365 | + except Exception as e: |
| 366 | + print(f"Warning: npm vulnerability checking failed: {e}") |
| 367 | + print(f"Traceback: {traceback.format_exc()}") |
| 368 | + |
| 369 | + all_vulnerabilities = { |
| 370 | + "vulnerabilities": ghad_vulnerabilities + nvd_vulnerabilities + npm_vulnerabilities |
| 371 | + } |
| 372 | + no_vulnerabilities_found = not ghad_vulnerabilities and not nvd_vulnerabilities and not npm_vulnerabilities |
| 373 | + if json_output: |
| 374 | + print(json.dumps(all_vulnerabilities, cls=VulnerabilityEncoder)) |
| 375 | + return EXIT_SUCCESS if no_vulnerabilities_found else EXIT_VULNERABILITIES_FOUND |
| 376 | + elif no_vulnerabilities_found: |
| 377 | + print(f"No new vulnerabilities found ({len(ignore_list)} ignored)") |
| 378 | + return EXIT_SUCCESS |
| 379 | + else: |
| 380 | + print("WARNING: New vulnerabilities found") |
| 381 | + for vuln in all_vulnerabilities["vulnerabilities"]: |
| 382 | + print( |
| 383 | + f"- {vuln.dependency} (version {vuln.version}) : {vuln.id} ({vuln.url})" |
| 384 | + ) |
| 385 | + print(f"\n{vulnerability_found_message}") |
| 386 | + return EXIT_VULNERABILITIES_FOUND |
| 387 | + except RequestException as exc: |
| 388 | + print(f"Error: vulnerability database request failed: {exc}") |
| 389 | + return EXIT_SCAN_ERROR |
| 390 | + except Exception as exc: |
| 391 | + print(f"Error: vulnerability scan failed: {exc}") |
| 392 | + print(traceback.format_exc()) |
| 393 | + return EXIT_SCAN_ERROR |
380 | 394 |
|
381 | 395 |
|
382 | 396 | if __name__ == "__main__": |
|
0 commit comments