Labels: bug, vulnerability-module
Severity: S1. Several defects make the findings view and dashboard silently wrong.
| Finding (path:line) |
Issue |
modules/vulnerability/adapters/ghsa.py:220-248 |
Creates a VulnerabilityMatch for every GHSA advisory mentioning a package without checking the installed version against the vulnerable range -> mass false positives; inflates counts and wastes scoring-LLM budget |
modules/vulnerability/api_router.py:82-83 |
_SEVERITY_ORDER keys are CVSS labels (CRITICAL...) but criticality values are policy categories (Immediate/High/Moderate/Planned) -> .get(...,99) returns 99 for every row -> default finding sort is meaningless; KEV tiebreak never fires |
modules/vulnerability/module.py:508-518 |
system_summary reads counts.get("critical"/"medium"/"low") but real values are immediate/moderate/planned -> dashboard shows 0 for 3 of 4 tiers |
modules/vulnerability/reporting/export_service.py:38-40 |
Export streams ALL LatestFindingRecord rows and ignores the run_id in the URL -> exported file does not match the report the user opened |
modules/vulnerability/providers/nvd.py:130-141 |
Rate-limiter releases the lock before time.sleep() -> two threads read the same slot and fire concurrently, violating the NVD limit (429 bursts) |
modules/vulnerability/providers/{nvd,epss,kev}.py |
Blocking httpx.Client + time.sleep() called from the async tool chain -> event-loop starvation (up to 6s/CVE); SSE heartbeats stall |
modules/vulnerability/api_router.py:162,254 |
facets + list_findings fetch all matching rows and paginate/count in memory -> O(N) memory per request; DoS amplifier at 10k+ findings |
modules/vulnerability/agents/scoring/agent.py:305-310 |
scoring_metadata handles only model/cache but normalize_scoring_mode() returns fallback -> else raises RuntimeError, aborting scoring notes / crashing report state |
modules/vulnerability/services/intel.py:185 |
cve_cache_ttl_hours=24 is dead code; enrichment is keep-forever -> stale NVD data persists unless force_refresh |
modules/vulnerability/api_router.py:658-685 |
bulk_update_findings allows any target workflow_state from any state -> closed can jump to new; no transition validation, no audit of progression |
Acceptance: GHSA matches gated on installed-version-in-range; severity order + summary keyed on the real criticality vocabulary; export honors run_id; provider I/O async with a correct rate-limiter; SQL-side pagination/facets; scoring_metadata handles fallback; TTL honored; workflow transitions validated.
Labels: bug, vulnerability-module
Severity: S1. Several defects make the findings view and dashboard silently wrong.
modules/vulnerability/adapters/ghsa.py:220-248VulnerabilityMatchfor every GHSA advisory mentioning a package without checking the installed version against the vulnerable range -> mass false positives; inflates counts and wastes scoring-LLM budgetmodules/vulnerability/api_router.py:82-83_SEVERITY_ORDERkeys are CVSS labels (CRITICAL...) butcriticalityvalues are policy categories (Immediate/High/Moderate/Planned) ->.get(...,99)returns 99 for every row -> default finding sort is meaningless; KEV tiebreak never firesmodules/vulnerability/module.py:508-518system_summaryreadscounts.get("critical"/"medium"/"low")but real values areimmediate/moderate/planned-> dashboard shows 0 for 3 of 4 tiersmodules/vulnerability/reporting/export_service.py:38-40LatestFindingRecordrows and ignores therun_idin the URL -> exported file does not match the report the user openedmodules/vulnerability/providers/nvd.py:130-141time.sleep()-> two threads read the same slot and fire concurrently, violating the NVD limit (429 bursts)modules/vulnerability/providers/{nvd,epss,kev}.pyhttpx.Client+time.sleep()called from the async tool chain -> event-loop starvation (up to 6s/CVE); SSE heartbeats stallmodules/vulnerability/api_router.py:162,254facets+list_findingsfetch all matching rows and paginate/count in memory -> O(N) memory per request; DoS amplifier at 10k+ findingsmodules/vulnerability/agents/scoring/agent.py:305-310scoring_metadatahandles onlymodel/cachebutnormalize_scoring_mode()returnsfallback->elseraisesRuntimeError, aborting scoring notes / crashing report statemodules/vulnerability/services/intel.py:185cve_cache_ttl_hours=24is dead code; enrichment is keep-forever -> stale NVD data persists unlessforce_refreshmodules/vulnerability/api_router.py:658-685bulk_update_findingsallows any targetworkflow_statefrom any state -> closed can jump to new; no transition validation, no audit of progressionAcceptance: GHSA matches gated on installed-version-in-range; severity order + summary keyed on the real criticality vocabulary; export honors
run_id; provider I/O async with a correct rate-limiter; SQL-side pagination/facets;scoring_metadatahandlesfallback; TTL honored; workflow transitions validated.