feat(cve): show all CVEs with fixable indicator in list screen
All checks were successful
Build and Release .deb / build-deb (push) Successful in 21s
All checks were successful
Build and Release .deb / build-deb (push) Successful in 21s
- filter_actionable_cves now marks all CVEs with 'fixable' boolean - cve_list in cache contains ALL CVEs (not just actionable ones) - CVEListScreen adds 'Corrigeable' column with 🟢/🔴 indicator - Sidebar counter still shows only actionable CVEs (cve_count)
This commit is contained in:
parent
e22f416500
commit
86eda73eb9
2 changed files with 37 additions and 20 deletions
|
|
@ -51,33 +51,34 @@ def _is_cve_actionable(cve_id: str, suite: str = "bookworm") -> bool:
|
||||||
|
|
||||||
|
|
||||||
def filter_actionable_cves(cves: list[dict]) -> tuple[list[dict], int]:
|
def filter_actionable_cves(cves: list[dict]) -> tuple[list[dict], int]:
|
||||||
"""Filtre la liste des CVE pour ne garder que les actionnables.
|
"""Filtre la liste des CVE pour ajouter un flag 'fixable'.
|
||||||
Retourne (cve_actionnables, cve_total)."""
|
Retourne (cve_avec_flag, nombre_actionnables)."""
|
||||||
if not cves:
|
if not cves:
|
||||||
return [], 0
|
return [], 0
|
||||||
|
|
||||||
total = len(cves)
|
def check(cve: dict) -> dict:
|
||||||
|
|
||||||
def check(cve: dict) -> dict | None:
|
|
||||||
try:
|
try:
|
||||||
if _is_cve_actionable(cve["id"]):
|
is_fixable = _is_cve_actionable(cve["id"])
|
||||||
return cve
|
cve["fixable"] = is_fixable
|
||||||
|
return cve
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
cve["fixable"] = False
|
||||||
return None
|
return cve
|
||||||
|
|
||||||
actionable = []
|
all_cves = []
|
||||||
|
actionable_count = 0
|
||||||
with ThreadPoolExecutor(max_workers=10) as executor:
|
with ThreadPoolExecutor(max_workers=10) as executor:
|
||||||
futures = [executor.submit(check, cve) for cve in cves]
|
futures = [executor.submit(check, cve) for cve in cves]
|
||||||
for future in futures:
|
for future in futures:
|
||||||
try:
|
try:
|
||||||
result = future.result()
|
cve = future.result()
|
||||||
if result:
|
all_cves.append(cve)
|
||||||
actionable.append(result)
|
if cve.get("fixable"):
|
||||||
|
actionable_count += 1
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
return actionable, total
|
return all_cves, actionable_count
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
|
|
@ -218,10 +219,10 @@ def scan_target(target: Target, progress_cb: Callable) -> ScanResult:
|
||||||
|
|
||||||
# Filtrer les CVE actionnables via l'API Debian
|
# Filtrer les CVE actionnables via l'API Debian
|
||||||
if cve_list:
|
if cve_list:
|
||||||
actionable, total = filter_actionable_cves(cve_list)
|
all_cves, actionable_count = filter_actionable_cves(cve_list)
|
||||||
result.cve_list = actionable
|
result.cve_list = all_cves
|
||||||
result.cve_count = len(actionable)
|
result.cve_count = actionable_count
|
||||||
result.cve_total = total
|
result.cve_total = len(all_cves)
|
||||||
else:
|
else:
|
||||||
result.cve_list = []
|
result.cve_list = []
|
||||||
result.cve_count = 0
|
result.cve_count = 0
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,21 @@ except Exception:
|
||||||
PYPERCLIP_OK = False
|
PYPERCLIP_OK = False
|
||||||
|
|
||||||
|
|
||||||
|
SCREEN_CSS = """
|
||||||
|
align: left top;
|
||||||
|
padding: 1 2;
|
||||||
|
#toolbar {
|
||||||
|
height: auto;
|
||||||
|
dock: top;
|
||||||
|
margin-bottom: 1;
|
||||||
|
}
|
||||||
|
DataTable {
|
||||||
|
height: 1fr;
|
||||||
|
border: solid $primary;
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
class PackageListScreen(Screen):
|
class PackageListScreen(Screen):
|
||||||
BINDINGS = [("b", "back", "Retour")]
|
BINDINGS = [("b", "back", "Retour")]
|
||||||
DEFAULT_CSS = """
|
DEFAULT_CSS = """
|
||||||
|
|
@ -75,14 +90,15 @@ class CVEListScreen(Screen):
|
||||||
with Horizontal(id="toolbar"):
|
with Horizontal(id="toolbar"):
|
||||||
yield Button("⬅ Retour", id="cve-back", variant="default")
|
yield Button("⬅ Retour", id="cve-back", variant="default")
|
||||||
table = DataTable(id="cve-table")
|
table = DataTable(id="cve-table")
|
||||||
table.add_columns("CVE-ID", "Paquet", "Lien")
|
table.add_columns("CVE-ID", "Paquet", "Corrigeable", "Lien")
|
||||||
table.cursor_type = "row"
|
table.cursor_type = "row"
|
||||||
for i, cve in enumerate(self.cves):
|
for i, cve in enumerate(self.cves):
|
||||||
cve_id = cve.get("id", "?")
|
cve_id = cve.get("id", "?")
|
||||||
pkg = cve.get("package", "?")
|
pkg = cve.get("package", "?")
|
||||||
url = cve.get("url", "")
|
url = cve.get("url", "")
|
||||||
|
fixable = "🟢 Oui" if cve.get("fixable") else "🔴 Non"
|
||||||
self.urls[i] = url
|
self.urls[i] = url
|
||||||
table.add_row(cve_id, pkg, url)
|
table.add_row(cve_id, pkg, fixable, url)
|
||||||
yield table
|
yield table
|
||||||
|
|
||||||
def on_data_table_row_selected(self, event: DataTable.RowSelected):
|
def on_data_table_row_selected(self, event: DataTable.RowSelected):
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue