Releases: btdt1983/vulnscan-ai
Release list
v0.4.10
Fix
- The interactive menu's "Network scan" entry (option 3) silently returned to the menu when
network_targetswasn't configured yet. It printed an explanatory hint but never paused before the next screen redraw, so on curses terminals the hint was wiped before it could be read.
Docs
- The
menucommand reference was missingcompliance,networkandauditfrom its list of covered commands. - The website's command table gained a dedicated row for
scan --scanner network(it previously only appeared as a scanner chip, unlike every other first-class command).
331 tests, bandit clean.
v0.4.9 — info offers to install nmap for the network scanner
info offers to install nmap for the network scanner
Recommends: weak dependencies (like nmap for the network scanner) only
auto-install on a fresh dnf install — an upgrade of an already-installed
vulnscan-ai does not retroactively pull in a newly added weak dependency.
vulnscan-ai info now explains exactly why the network scanner is
unavailable (missing network_targets config, missing nmap, or both)
instead of just printing "unavailable", and when nmap is the only thing
missing it offers to install it right there via dnf install -y nmap
(interactively, TTY only) or prints the command to run yourself otherwise.
328 tests, bandit clean.
v0.4.8 — network exposure scanner
Network exposure scanner (10th scanner)
New network scanner: the first scanner that inspects hosts OTHER than the
one it runs on. Shells out to nmap -sV for host discovery, a scoped port
scan and service/version detection, then flags the same plaintext/legacy-
protocol and sensitive-service exposures as the ports scanner (shared risk
taxonomy, extracted into net_classify.py) — the same risk model, observed
remotely instead of via local ss. No CVE/CPE matching on detected service
versions yet (parked for a later phase).
Safety: gated on an explicit, config-only network_targets allow-list
(hosts/CIDRs you are authorized to test) — never a CLI flag, no env
override. The scanner stays genuinely unavailable until configured, and
prints an authorization reminder on every real invocation. Findings for a
target-bearing host are detection-only: remediation.py hard-refuses to
propose or execute commands against them, since a fix for a remote host
cannot run on this one.
New "Network scan" menu entry. Optional Recommends: nmap (degrades
gracefully if absent). 323 tests, bandit clean.
Install: see https://repo.techhack.nl
0.4.7 — audit-driven correctness & security hardening
0.4.7 — audit-driven correctness & security hardening
A adversarial review of the whole codebase; every real defect it surfaced is fixed. No user-facing surface change (no new commands, flags, or config keys).
Truthfulness (remediation engine)
- Auto-rollback now reports honestly. A rollback whose file restore or service revert failed no longer stamps a clean rollback — the CLI and the audit log were reporting "reverted, service left healthy" on a half-reverted host.
- Empty plans are no longer "applied". A prose-only fix plan (no commands) is no longer reported as applied; the dashboard apply path was writing a false
appliedaudit entry for a no-op.
Security
- Exported-script heredoc break-out closed.
fix --export-scriptnow uses a unique heredoc delimiter, so crafted/hallucinated file content can't terminate the heredoc early and inject commands the operator runs as root. - OVAL decompression-bomb guard. The OVAL feed is now decompressed with a size cap (it runs as root during
update-oval/ auto-refresh) and refuses a DOCTYPE.
Robustness — never abort the scan
- Malformed CVE-feed JSON (NVD / EPSS / CISA-KEV) can no longer crash a whole scan; enrichment fails per-finding.
- A package-less oscap advisory is no longer dropped on an empty-but-successful
updateinfoset — that was silently hiding real, unpatched advisories.
Lower-severity
Null-tolerant report/dashboard rendering, version-ordered (not install-ordered) kernel-currency check, corrupt-config tolerance, string-aware model-JSON extraction, a capped dashboard request body, and more.
305 tests (+12 regressions), bandit medium+ clean.
Install / upgrade
Existing techhack-repo users: sudo dnf upgrade vulnscan-ai
Fresh install: https://vulnscan-ai.techhack.nl
v0.4.6 — SCAP-grounded AI remediation prompts
For config/service findings (ssh/systemd/ports/webroot), the fix AI step is now
optionally grounded with a vetted remediation snippet retrieved from the host's
own SCAP Security Guide (SSG) XCCDF datastream (the same one scan --compliance
reads) — real peer-reviewed fix scripts already sitting on the host, unused until
now. Lightweight lexical matching only (no ML/embeddings, no fine-tuning): a
candidate rule must clear both a cosine-similarity floor and a minimum number of
distinct overlapping tokens before it's offered to the model as an optional,
adapt-don't-copy reference.
- New
vulnscanai/scap_kb.py. - New config key
scap_grounding(default true), CLI flagfix --no-scap-grounding. - Silent no-op when
scap-security-guideisn't installed — same behaviour as before. - Package/CVE findings (dnf/oscap) are unaffected.
- 293 tests (+16), bandit clean.
v0.4.5 — FIPS-posture scanner
FIPS-posture scanner (fips, 9th scanner)
The tool is FIPS-aware — this new scanner audits its own ground: is the host's cryptography actually hardened? It reads /proc/sys/crypto/fips_enabled, /proc/cmdline and the crypto-policies state files (plus fips-mode-setup --check when present) and reports only real gaps:
- Half-enabled FIPS — kernel in FIPS mode but the system crypto-policy is not (so OpenSSL/GnuTLS/OpenSSH still negotiate non-approved algorithms), or the reverse — important.
- Inconsistent state per
fips-mode-setup --check— important. - Weakened crypto-policy —
LEGACY, or a SHA-1-restoring sub-policy such asDEFAULT:SHA1— flagged on any host, FIPS or not. - Pending policy change — configured ≠ applied (the crypto analogue of "a patch on disk is not a patch in RAM") — moderate.
- FIPS required but not enabled — important, only when the config sets
fips_required: true.
A consistent non-FIPS host is a legitimate configuration and produces no findings (no false positives). Pure stdlib; in --all, not in the default scanner set.
Also: info now shows the active crypto-policy; new config key fips_required (default false); fixed the stale --scanner help list.
277 tests, bandit clean. Signed el9 + el10 packages are on https://repo.techhack.nl.
vulnscan-ai 0.4.4
Effective-state scanner — a patch on disk is not a patch in RAM
New read-only effective scanner reports what the running system is still using:
- Kernel currency — running kernel vs newest installed. If an update landed but the host hasn't rebooted, it keeps executing the OLD (vulnerable) kernel while the package scanners report it patched. → one reboot required finding (
important). A membership check avoids false positives on kernel-rt/debug hosts. - Superseded libraries in use — a process still mapping a deleted/replaced library (
.soupdated on disk but the running process holds the old code) needs a restart. Reads/proc/<pid>/mapsand maps each PID to its systemd unit via/proc/<pid>/cgroup→ per-service restart to load the update finding. Deleted core libraries (glibc/loader/systemd) imply a reboot.
Pure stdlib (/proc + rpm); uses dnf-utils' needs-restarting -r as the authoritative reboot verdict when present (now a Recommends).
fix now overwrites a package fix's requires_reboot with this ground truth after applying — the "reboot required" note is a fact, not an AI guess. And reboot/shutdown/poweroff/halt/kexec/init 0,6/systemctl reboot are on the deny-list: a fix never takes the host down itself — rebooting stays the operator's call.
Run it with --scanner effective or --all. 259 tests, bandit clean. Signed el9 + el10 packages below; install via https://repo.techhack.nl
vulnscan-ai 0.4.3
Offline deterministic remediation catalog — fix works air-gapped
Package/advisory findings (dnf/oscap) are now planned by a deterministic offline catalog with no AI call and no network: a scoped dnf update -y --advisory=<id> (or dnf update -y <package>) built locally. A host with no AI provider configured is no longer a dead end, and package fixes are reproducible (same finding → same plan). The AI provider is reserved for config/service findings that genuinely need reasoning.
New:
fix --offline— plan only from the catalog, never call a provider (air-gapped); config findings that need reasoning are reported as "no offline plan" and skipped.fix --no-catalog— disable the catalog, use the AI provider for every finding.- config key
offline_catalog(defaulttrue;--offlineoverrides it).
Safety: command construction is injection-safe — the advisory is accepted only on a full-string match and the package name is allowlist-validated, so a crafted finding cannot inject extra dnf arguments (in-process or in an exported script). Plans still pass the deny-list / no-shell screen and require approval.
The web dashboard's apply-fix is catalog-first too, and scheduled --plan produces a deterministic plan offline. Findings with no offline plan are surfaced and skipped (never falsely reported as applied).
244 tests, bandit clean. Signed el9 + el10 packages below; install via the signed repo at https://repo.techhack.nl.
vulnscan-ai 0.4.2
Structured file writes — config/drop-in fixes apply in-process again
Closes the gap the 0.4.1 no-shell hardening opened. A fix that creates or replaces a file (e.g. a systemd hardening drop-in) now carries the file path + content, and the transactional engine writes it safely without a shell — snapshot → write → validate → reload — with rollback that removes a created file or restores an overwritten one. Previously such a fix was honestly blocked and only worked via --export-script.
- New
write_filesremediation field; the model is prompted to use it instead of a shell redirect. Sanitised (absolute path only) and stripped from package-CVE findings. - Write targets are screened (no
/etc/shadow,/etc/passwd,/dev|/proc|/sys|/boot, directories). fix --export-script/--export-ansiblerender the writes too (bash heredoc / Ansible copy-with-content); the exported rollback now removes a created file, matching the in-process engine.
+11 tests (227), integration suite green, bandit clean.
Upgrade
sudo dnf upgrade --refresh vulnscan-ai
vulnscan-ai 0.4.1
Stability release
Hardening of what the tool already does — no new surface. Focus: the code paths that change your system must be trustworthy, and nothing should ever dump a traceback.
- Rollback no longer lies.
rollback(and the automatic rollback) now report the true outcome; a missing/partial restore surfaces as ROLLBACK INCOMPLETE instead of a false "reverted", and the audit log records it truthfully. - No more false-success fixes. A fix command that needs a shell (redirect/pipe/
&&/$( )) — which the no-shell runner can't execute as written — is now blocked with a pointer to--export-script, instead of runningecho … > fileas a silent no-op and reporting "applied". - Parser robustness. The scanner/feed parsers skip malformed external data (a null item or wrong-typed field in CISA KEV / Rocky Apollo JSON or a container inspect object) instead of crashing
news/container scans. - Never-crash CLI. An unexpected error prints a readable message and exits non-zero instead of a traceback (
VULNSCANAI_DEBUG=1re-raises); a corrupt config orfindings.jsondegrades with a warning. - Tests: +22 unit tests (a fuzz battery for every parser, engine rollback/shell cases, never-crash paths) plus an opt-in integration suite that runs the real
ss/systemd-analyze/oscapand the scanners against a live host (VULNSCANAI_INTEGRATION=1).
Install / upgrade
sudo dnf upgrade --refresh vulnscan-ai