Appearance
Changelog
This page summarizes the notable changes to NetVuln Tool through the current release (v4.20.0). The complete, authoritative history lives in the CHANGELOG.md file at the repository root and follows the Keep a Changelog format.
The project follows semantic versioning. Stable releases are tagged vX.Y.Z on main; dev is the integration branch. Version bumps and releases are automated by the CI pipeline (see Contributing).
Unreleased
Work merged to dev and not yet cut to a stable tag. There is none at the moment; dev and the latest stable tag (v4.20.0) are in sync.
[4.20.0] - 2026-09-09
The first release published through the Community Edition export pipeline (see 4.10.0 below).
Added
- Posture-steered demo report pipeline (#323):
synthetic_collection.shgained a--posturesteering knob (severity mix presets) and a--resolved-rateoption for marking remediation entries resolved. A newscripts/demo_report.shbuilds a complete fictional engagement report end to end, filling in the Compliance, ORC 9.64, Topology, and Benchmark tabs that synthetic sessions previously left empty, and a newscripts/seed_demo_portal.shuploads the result to a portal environment for demo and marketing use.
Fixed
- The Community Edition export gate now fails on markdown links whose targets are excluded from the export (#333): a link pointing at a path the export removes previously shipped through unnoticed and 404'd for a public reader. The links this missed are rewritten to plain text.
- Demo portal session ids now satisfy the portal's id-format rules (#334): dots in the tool version broke several portal endpoints; the seeding script now substitutes underscores.
[4.10.0] - 2026-09-08
Added
- Community Edition export pipeline (#315): a new
scripts/publish_public.sh, driven by declarative exclude and redaction data files, publishes a sanitized snapshot of each tagged release to the public mirror atgitlab.com/netvulntool/netvuln-tool. A leak check fails the export closed on any remaining internal infrastructure detail, and the same check runs as a dry run on every pull request so a leak fails the PR that introduces it rather than the release that ships it. Each real publish also builds a deterministic source tarball and checksum with permanent download links. AddsTRADEMARKS.md.
Fixed
- Release CI pins npm 12 in the Verify job too (#313, #318), matching the earlier client-tests fix, after the same npm crash blocked a release push.
- The license e2e suite fails loud instead of crashing on a non-JSON portal response, and warms up the licenses API before its first write (#317, #320).
- The license e2e verbose request trace now goes to stderr, so captured responses stay pure JSON for parsing (#321, #322).
[4.9.0] through [4.9.3] - 2026-09-02 to 2026-09-05
Added
- Dedicated
nvtservice account and/opt/netvuln-toolinstall layout (#297), mandatory on Raspberry Pi and opt-in elsewhere, with a migration script for an existing hand-patched install.
Changed
- Every tracked shell script is now committed executable, guarded in CI so the bit cannot silently disappear again (#302).
Fixed
- A C2 scan killed by its timeout now finalizes and uploads a complete report instead of a partial or truncated one (#306).
- Daemon-spawned scans now honor the configured base directory for sessions and logs (#307).
- The e2e Identity login now percent-encodes credentials, fixing failures on passwords containing special characters (#311).
[4.8.0] through [4.8.10] - 2026-08-21 to 2026-09-01
Added
- C2
run_scanandpush_sessiongained apost_scanmodule list (compliance, topology, exec summary), so a remote scan or re-upload can populate those report sections without a full rescan (#229, #239). - C2 command dedup for at-least-once delivery (#243), so a redelivered command is reported rather than re-executed.
- A daemon troubleshooting runbook joined the docs site (#281).
- Report Compliance tab finding IDs are now clickable, and
REPORT_HIDE_CONSULTATIONsuppresses the professional-review upsell blocks for engagement-scoped reports (#268, #269).
Changed
- C2 commands are now available from the business license tier, not just MSP (#246).
Fixed
- C2
updateandrestartnow re-exec the daemon, so updated code takes effect immediately instead of waiting for a manual restart (#205). - C2
run_scanhonors a per-command timeout and uploads even on a non-zero exit; scheduled uploads retry with backoff (#266, #267, #270). - An interrupted or timed-out scan now uploads a populated summary instead of zeros (#290).
- C2
run_scanno longer breaks on a target list with a space after the comma (#286).
[4.7.0] - 2026-08-21
Added
- C2
run_scanpost-scan modules (#229): the daemon can wire compliance, topology, and executive-summary generation into a remotely triggered scan.
Fixed
refresh_reports.shnow sends the Identity JWT its download endpoint requires (#227).- Docs no longer frame the collection portal under its old repository name after the move (#137).
[4.6.0] - 2026-08-18
Fixed
- Daemon-uploaded sessions now include a generated report, fixing the portal's View/Report/PDF buttons for agent-uploaded scans (#217).
- nmap's raw-scan capability now survives a package upgrade, and the daemon self-checks and reports it each heartbeat (#215).
[4.5.0] - 2026-08-15
Changed
install.shinstalls the full scanner toolchain by default, not just nmap, with a--minimalopt-out (#208).- The daemon runs privileged nmap scans without running as root, via ambient capabilities (#209).
Fixed
- C2 command output is stripped of ANSI escape codes before reaching the portal (#210).
[4.4.0] through [4.4.6] - 2026-08-06 to 2026-08-15
Added
lib/portal_api.sh, a single bash client for the portal's session listing, backing a hardened bulk refresh inrefresh_reports.sh(#145).
Fixed
- Agent id derivation unified into one function, keyed off a stable machine id instead of hostname, fixing duplicate agent registrations across a restart or reinstall (#193, #206).
- C2
run_scanno longer failed with "Scanner not found" on a fresh install (#199). - Daemon status now refreshes continuously instead of only on a manual signal (#194).
- Release tooling hardened against a symlinked
CLAUDE.mdand other doc-drift gaps (#165, #124).
[4.3.4] through [4.3.10] - 2026-07-24 to 2026-08-04
Added
- A house style checker enforces the no-em-dash prose rule across published docs (#129, #130).
Fixed
- The Identity JWT is now sent in the correct header everywhere it is used, closing the Netlify edge's silent rejection of the previous header (#147, #150).
- The public docs site was sanitized of remaining internal infrastructure references (#109, #110).
- Bash-module findings reached the session JSON again on the Python orchestrator path, and session files are now created with owner-only permissions (#111, #112, #121).
[4.3.3] - 2026-07-22
Added
- Docs site custom domain and SEO (#101): the documentation site is served from its own domain, docs.netvulntool.com, and now emits a
sitemap.xmlplus per-page canonical links so search engines index the branded address. - Doc version-drift guard and auto-sync (#102, #104):
scripts/bump_version.shnow also rewrites theCLAUDE.md"Current version" line and theREADME.mdtitle on every bump, andrelease_check.ymlfails a release PR when either doc pointer does not matchVERSION, ending the recurring drift where the docs fell behind the released version (#78, #79, #80).
[4.3.2] - 2026-07-22
Fixed
- E2E smoke test broke on whitespace in a CI secret: the
e2e.ymlworkflow now strips all whitespace fromCONSULTATION_API_URLandCONSULTATION_API_KEYbefore use, so a stray leading space or trailing newline in a secret value no longer makescurlreject the URL (every check had returned code000).
[4.3.1] - 2026-07-18
Added
- Documentation site auto-deploy: the VitePress docs site (
site/) is published and redeploys automatically on every push tomainthat touchessite/**, via a CI workflow that builds the site and deploys it through the Netlify CLI.
Fixed
- Docs site Portal nav link now points to the collection portal (
bullium.com/collect/) instead of the marketing homepage (#96).
[4.3.0] - 2026-07-18
Added
- End-user installer
install.sh: a deployment installer (distinct from the developersetup.sh) that provisions a machine as a scanner agent in one idempotent, scriptable run: dependency preflight,netvulnCLI install, license-key install, config scaffold with scanning left disabled, systemd daemon install on Linux, and portal connectivity verification. Fully flag-driven for CI and automation. - VitePress documentation site (
site/): this self-contained help system, covering install, setup, CLI reference, architecture, guides, and API reference, refreshed to the current feature set and replacing the prior stale docs. - WiFi access-point discovery (#71):
scripts/discover_wifi.sh, an opt-in standalone Linux-only scanner that enumerates nearby access points in managed mode vianmcli(0-100 link quality) oriw(dBm), with a guarded best-effort--monitorcapture path (aircrack-ng). Emitswifi_scan_results.json. See WiFi Discovery. - Field-appliance enclosure design (#74): a proprietary two-part 3D-printed case for a Raspberry Pi 5 plus RTL-SDR under
appliance/(OpenSCAD source, print-ready STLs, renders, assembly guide). The subtree is All Rights Reserved, not Apache-2.0, and is excluded from the published container image (see Open Source Boundary). docker-compose.yml: one-command containerized scans (docker compose run --rm scan recon -t <lan>), pre-wiring host networking and the sessions volume so privileged scans need no cap flags (#65). See Docker.- C2 session visibility and on-demand push (#86):
run_scancaptures and reports the session id it created and accepts an optionalupload: truepayload to push results to the portal; a newpush_sessioncommand uploads an existing session on demand (path-traversal validated). See Command and Control. - C2 operator guide and persisted
push_configoverrides (#84): new C2 operator guide; pushed config overrides now persist across daemon reload and restart via.c2_overrides.conf.
Fixed
-P stealthsilently ran a default scan (#88): the stealth profile variables were renamed so-P stealthresolves to the intended low-and-slow profile instead of falling back to the loader defaults.- C2
run_scanwithprofile: quickalways failed (#86):quick/quick_reconnow correctly map to-P quick_reconinstead of a nonexistent--quickflag. - Host discovery silently swallowed nmap crashes (#82): discovery now runs one nmap per target, captures stderr to
host_discovery.err, and surfaces a signal-death (rc >= 128) as a loud error plus an info-severity finding rather than reporting "0 hosts found". - WiFi findings mislabeled the signal unit (#73): normalized records now carry a per-backend unit (
link quality %for nmcli,dBmfor iw). - Privileged scans from the container (#65): the Dockerfile grants
cap_net_raw+eipon the nmap binary and setsNMAP_PRIVILEGED=1, so the non-root user gets full privileged scans with a plaindocker run. - HTML report not generated by the Python orchestrator (#66):
generate_html_reportnow self-initializesNV_JSON_MODEwhen unset.
[4.2.4] - 2026-07-04
Fixed
- E2E smoke test share-lookup false failure (#62):
scripts/e2e_smoke_test.shnow includes a minimalreport_htmlpart in the upload round-trip, so the portal stores a report blob and the share-token lookup returns 200. Added a BATS regression test. (1036 BATS + 143 client + 436 Python tests.)
[4.2.3] - 2026-07-04
Added
- Session license metadata plus business-tier gating (#46): the scan pipeline stamps a license block (tier, source, key fingerprint, validated-at timestamp; never the plaintext key) into every session JSON, mirroring the Python orchestrator. Webhook alert channels and remediation tracking now require an active business/MSP license, degrading gracefully on lower tiers.
Fixed
- Wrong tool version stamped in reports (#52):
NV_VERSIONnow derives from theVERSIONfile at source time (was hardcoded2.7.0), so report footers, sessiontool_version, and the exec summary render the correct version.bump_version.shconsistency-checks the fallback pin.
CI
release.ymlruns the BATS assertion lint (#47), matchingci.ymland the pre-commit hook.
[4.2.0] - [4.2.2]
Added
- Container image (#54): a single-stage Alpine
Dockerfilebundling the full recon toolchain (nmap plus NSE, bash, coreutils, jq, bind-tools, whois, openssl, samba-client, net-snmp-tools) and the source tree, run as a non-rootnetvulnuser. Published to a container registry via.gitea/workflows/publish-image.yml(:latestplus:<VERSION>). See Docker.
Fixed
- v4.2.1 container publish hardening (#54): lowercase the repository path for buildx, plus a fail-fast preflight that verifies
REGISTRY_USER/REGISTRY_TOKENare set. - v4.2.2 CI/release BATS runner consistency: both workflows force-install a pinned bats v1.13.0 so a stale pre-installed bats cannot mis-parse heredoc test fixtures and skip release tagging.
[4.1.0] - 2026-06-10
Added
- Unified license key model (#40):
NV_API_KEYis the canonical license, with identical bash and Python resolution precedence (NV_LICENSE_KEY,NV_API_KEY,CONSULTATION_API_KEY,~/.netvuln/license.key). Keys parse againstnvt_{pro|biz|msp}_{64hex}; the tier drives a feature gate matrix (soft gates that warn and skip, never blocking core scanning). See License Provisioning. - Online license validation with cache and grace (#40):
lib/license_validate.shandnetvuln/license.pyqueryGET /api/licensewith a 24h cache and a 72h offline grace window (fingerprint only, mode 600 cache). - ORC 9.64 compliance framework (#41): maps findings to the five technical divisions of Ohio Revised Code 9.64, with a readiness report tab, executive summary block, statutory deadlines, and attestation checklist. Opt-in and business-tier gated. See Compliance Mapping.
- BATS assertion convention plus lint (#42):
scripts/check_bats_assertions.shand a canary suite.
Fixed
- Mid-test BATS assertions silently passing on bash < 4.1 (#42): 1,452 bare standalone
[[ ... ]]assertions across 37 suites are now guarded with|| false(the upstream-documented fix). CI on Debian was never affected; exposure was local dev on macOS/bin/bash3.2.
[4.0.0] - [4.0.4]
Added
- Automated CI versioning (#28):
VERSIONas the single source of truth,scripts/bump_version.sh(patch/minor/major) atomically updatingVERSION,pyproject.toml, andnetvuln/__init__.py;release_check.ymlenforces the bump on PRs tomain;release.ymlauto-creates the git tag and release with generated notes on merge. - Python quality CI job:
python-checksruns pytest plus mypy via venv.
Fixed
- v4.0.1 - v4.0.4 release-pipeline hardening:
workflow_dispatchmanual fallback, a fix for a column-0 Python heredoc that broke therelease.ymlYAML, and aworkflow-yamlCI job (scripts/validate_workflows.py) that catches the heredoc trap at PR time.
[3.3.0] - [3.5.0] Python orchestrator
Added
- Python orchestrator (#v3.3.0): the
netvuln/package with a full CLI (recon/scan/upload/push/diff/status/version), a pipeline runner, nmap XML parsing, a native scoring engine (A-F grades, dual model), native HTTP upload and diff, strict mypy, and apy.typedmarker.pip install -e .provides thenetvulnconsole script. See Python Orchestrator. - Pipeline plugin hooks, license soft gate, and progress callbacks (v3.4.0):
_run_hooks()fires at phase boundaries;netvuln status --remotelists portal sessions via JWT;netvuln daemonwrapsnetvuln_daemon_ctl.sh. - Parallel module execution (v3.5.0): independent enumeration and report modules run concurrently via
ThreadPoolExecutorwith per-module temp JSON merge; the pre-push test hook is split from pre-commit. - C2 command handler and plugin architecture (v3.3.0):
lib/command_handler.sh(run_scan, update_schedule, push_config, restart, shutdown, update, set_log_level) andlib/plugin_loader.sh.api_debug.shportal debug tool.
[3.2.0] - [3.2.1] Compliance and topology
Added
- Compliance framework mapping: automatic finding-to-control mapping for CIS Controls v8, NIST CSF, PCI-DSS v4.0, and SOC 2 with gap analysis (
compliance_mapper.sh), plus a Compliance report tab. - Network topology visualization: per-host risk scoring, subnet grouping, and an inline SVG network map in reports (
network_topology.sh); a D3.js force-directed graph in the portal.
[3.1.0] - 2026-03-03
Added
- Synthetic collection generator (
synthetic_collection.sh) for test datasets with configurable severity mix and trends. - Exception / accept-liability workflow (
remediation_update.sh --accept/--revoke) with justification, approver, and optional auto-expiry. - Dual scoring model: an operational risk score (post-exceptions) alongside the actual risk score (
risk_score.sh), with a portal risk register.
[3.0.0] - 2026-03-03
Added
- Persistent scheduling daemon (
netvuln_daemon.sh) replacing cron: multi-config management, a pure-bash cron expression engine, exponential-backoff retry, portal health heartbeats, and signal-driven lifecycle (SIGHUP/SIGTERM/SIGUSR1). - Daemon control CLI (
netvuln_daemon_ctl.sh) with systemd install/uninstall and a service unit template. See Daemon Mode.
2.x series (2026-02 to 2026-03)
The 2.x line built out the core assessment and reporting stack:
- v2.15.0 template engine for executive summaries (Mustache-like syntax, PDF export, custom templates).
- v2.14.0 report white-labeling (config-driven branding, CSS overrides) and
CLIENT_IDmulti-tenancy scoping. - v2.12.0 - v2.13.0 platform validation (
pi_validate.sh), missed-scan detection (schedule_monitor.sh), and multi-config schedule management (schedule_list.sh,schedule_status.sh). - v2.11.0 cross-platform support for macOS and Linux/Debian (Raspberry Pi), with platform detection helpers.
- v2.9.0 - v2.10.0 alert result capture, executive summary upload, schedule metadata injection, health endpoint, and E2E smoke tests.
- v2.8.0 the risk scoring engine (A-F grades, trend analysis), email security assessment (SPF/DKIM/DMARC), cross-session remediation tracking, the scan diff CLI (CI exit code 2), and multi-channel alerts (email/Slack/webhook).
- v2.0 - v2.7.0 the multi-phase recon pipeline, self-contained HTML reports (tabs, pagination), CVE/CVSS lookup, the consultation upload portal, and the remediation playbook.
Version history (quick reference)
| Version | Tag | Highlights |
|---|---|---|
| 4.20.0 | v4.20.0 | First Community Edition release; posture-steered demo report pipeline (#323) |
| 4.10.0 | v4.10.0 | Community Edition export pipeline to the public GitLab mirror (#315) |
| 4.9.0 - 4.9.3 | v4.9.x | Dedicated nvt service account and /opt install layout; executable-bit guard; timeout-finalize hardening (#297, #302, #306) |
| 4.8.0 - 4.8.10 | v4.8.x | C2 push_session post-scan regeneration and command dedup; business-tier C2 access; daemon troubleshooting runbook (#239, #243, #246, #281) |
| 4.7.0 | v4.7.0 | C2 run_scan post-scan modules; refresh_reports.sh Identity JWT fix (#229, #227) |
| 4.6.0 | v4.6.0 | Daemon-uploaded sessions include a generated report; raw-scan capability survives nmap upgrades (#217, #215) |
| 4.5.0 | v4.5.0 | Full toolchain install by default; rootless privileged scans; ANSI-clean C2 output (#208, #209, #210) |
| 4.4.0 - 4.4.6 | v4.4.x | Portal session-listing client and hardened refresh; unified stable agent id; daemon status fixes (#145, #193, #194) |
| 4.3.4 - 4.3.10 | v4.3.x | Public docs sanitization; house style checker; Identity JWT header fix (#109, #129, #147) |
| 4.3.3 | v4.3.3 | Docs custom domain + SEO (#101); doc version-drift guard + auto-sync (#102, #104) |
| 4.3.2 | v4.3.2 | E2E smoke-test whitespace-strip fix |
| 4.3.1 | v4.3.1 | Docs site CI auto-deploy; Portal nav link fix (#96) |
| 4.3.0 | v4.3.0 | End-user installer (install.sh), VitePress docs site, WiFi discovery (#71), appliance design (#74), docker-compose (#65), C2 session push (#84, #86); 1104 BATS + 143 client + 436 Python tests |
| 4.2.4 | v4.2.4 | E2E smoke test share round-trip fix (#62); 1036 BATS + 143 client + 436 Python tests |
| 4.2.3 | v4.2.3 | Session license metadata + business-tier gating (#46); NV_VERSION from VERSION file (#52) |
| 4.2.0 - 4.2.2 | v4.2.x | Containerized Alpine image published to a container registry (#54); publish + bats-pin hardening |
| 4.1.0 | v4.1.0 | Unified license model + online validation; ORC 9.64 framework; BATS || false sweep (#40, #41, #42) |
| 4.0.0 - 4.0.4 | v4.0.x | Automated CI versioning + auto-tagging; Python quality CI; release-pipeline hardening (#28) |
| 3.3.0 - 3.5.0 | v3.3-3.5 | Python orchestrator (full CLI, native scoring/upload/diff, strict mypy); plugin hooks; parallel modules |
| 3.2.0 - 3.2.1 | v3.2.x | Compliance mapping (CIS v8, NIST CSF, PCI-DSS v4.0, SOC 2); network topology visualization |
| 3.1.0 | v3.1.0 | Synthetic collections; exception/accept-liability workflow; dual scoring model |
| 3.0.0 | v3.0.0 | Persistent scheduling daemon; daemon control CLI; systemd integration |
| 2.8.0 - 2.15.0 | v2.8-2.15 | Risk scoring, email security, remediation tracking, alerts, exec summaries, white-labeling, scheduling |
| 2.0 - 2.7.0 | v2.x | Multi-phase recon pipeline, HTML reports, CVE lookup, portal upload, remediation playbook |
| 1.0 | v1.0.0 | Initial release: 4 scan modes, CSV export, logging |
For the full entry-by-entry history, including every patch release and portal companion note, read the CHANGELOG.md file in the repository.
