fix(scan): never auto-resolve on inactive assets; show real sync counters

A disconnected Wazuh agent still serves its LAST STORED syscollector data,
so the app scan 'succeeds' on data that can be months old and then closes
findings from it. Wazuh's own vuln sync only walks active agents, so
nothing ever reopens them — the tester's disconnected host ended up with
zero CVEs in TrueVuln while Wazuh still listed 31 for it. The app-scan
reconcile now runs only when the asset is ACTIVE; skipped ones are counted.

Sync result message now reports what actually happened (CVE reports seen,
created / updated / reopened / confirmed / patched) instead of three
counters that were mostly structurally zero.
This commit is contained in:
2026-07-25 21:23:17 +02:00
parent 6ff2076164
commit d81a993bbe
2 changed files with 22 additions and 3 deletions
+9 -1
View File
@@ -2084,7 +2084,15 @@ def run_wazuh_vulnerability_sync(db: Session) -> dict:
logger.warning(f"Wazuh sync: new-vuln notification dispatch failed: {e}")
return {
"message": f"Synced {stats['agents_synced']} agents. Created: {stats['vulns_created']}, Updated: {stats['vulns_updated']}, Patched: {stats['vulns_patched']}",
"message": (
f"Synced {stats['agents_synced']} agents, "
f"{stats.get('total_vulns_from_wazuh', 0)} CVE reports. "
f"Created: {stats['vulns_created']}, "
f"Updated: {stats['vulns_updated']}, "
f"Reopened: {stats.get('vulns_reopened', 0)}, "
f"Confirmed: {stats.get('vulns_confirmed', 0)}, "
f"Patched: {stats['vulns_patched']}"
),
**stats
}
+13 -2
View File
@@ -752,8 +752,19 @@ def run_app_cve_scan(db: Session, asset_id: Optional[int] = None) -> dict:
# the software was updated/removed past it. Only safe when we had a
# real inventory this run (packages non-empty) — else we'd close
# everything on a transient fetch failure.
stats["resolved"] = stats.get("resolved", 0) + _resolve_stale_app_findings(
db, asset, touched_cves)
#
# AND only on a LIVE asset. A disconnected Wazuh agent still serves
# its last stored syscollector data, so the scan "succeeds" on data
# that may be months old — closing findings from it is unprovable
# (tester: a disconnected host ended up with zero CVEs while Wazuh
# still listed 31 for it). Wazuh's own vuln sync skips inactive
# agents too, so nothing would ever reopen them.
from app.models.asset import AssetStatus
if asset.status == AssetStatus.ACTIVE:
stats["resolved"] = stats.get("resolved", 0) + _resolve_stale_app_findings(
db, asset, touched_cves)
else:
stats["resolve_skipped_inactive"] = stats.get("resolve_skipped_inactive", 0) + 1
if touched:
stats["assets"] += 1