Skip to content

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.sh gained a --posture steering knob (severity mix presets) and a --resolved-rate option for marking remediation entries resolved. A new scripts/demo_report.sh builds 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 new scripts/seed_demo_portal.sh uploads 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 at gitlab.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. Adds TRADEMARKS.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 nvt service account and /opt/netvuln-tool install 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_scan and push_session gained a post_scan module 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_CONSULTATION suppresses 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 update and restart now re-exec the daemon, so updated code takes effect immediately instead of waiting for a manual restart (#205).
  • C2 run_scan honors 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_scan no longer breaks on a target list with a space after the comma (#286).

[4.7.0] - 2026-08-21

Added

  • C2 run_scan post-scan modules (#229): the daemon can wire compliance, topology, and executive-summary generation into a remotely triggered scan.

Fixed

  • refresh_reports.sh now 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.sh installs the full scanner toolchain by default, not just nmap, with a --minimal opt-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 in refresh_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_scan no 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.md and 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.xml plus per-page canonical links so search engines index the branded address.
  • Doc version-drift guard and auto-sync (#102, #104): scripts/bump_version.sh now also rewrites the CLAUDE.md "Current version" line and the README.md title on every bump, and release_check.yml fails a release PR when either doc pointer does not match VERSION, 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.yml workflow now strips all whitespace from CONSULTATION_API_URL and CONSULTATION_API_KEY before use, so a stray leading space or trailing newline in a secret value no longer makes curl reject the URL (every check had returned code 000).

[4.3.1] - 2026-07-18

Added

  • Documentation site auto-deploy: the VitePress docs site (site/) is published and redeploys automatically on every push to main that touches site/**, 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 developer setup.sh) that provisions a machine as a scanner agent in one idempotent, scriptable run: dependency preflight, netvuln CLI 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 via nmcli (0-100 link quality) or iw (dBm), with a guarded best-effort --monitor capture path (aircrack-ng). Emits wifi_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_scan captures and reports the session id it created and accepts an optional upload: true payload to push results to the portal; a new push_session command uploads an existing session on demand (path-traversal validated). See Command and Control.
  • C2 operator guide and persisted push_config overrides (#84): new C2 operator guide; pushed config overrides now persist across daemon reload and restart via .c2_overrides.conf.

Fixed

  • -P stealth silently ran a default scan (#88): the stealth profile variables were renamed so -P stealth resolves to the intended low-and-slow profile instead of falling back to the loader defaults.
  • C2 run_scan with profile: quick always failed (#86): quick/quick_recon now correctly map to -P quick_recon instead of a nonexistent --quick flag.
  • 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, dBm for iw).
  • Privileged scans from the container (#65): the Dockerfile grants cap_net_raw+eip on the nmap binary and sets NMAP_PRIVILEGED=1, so the non-root user gets full privileged scans with a plain docker run.
  • HTML report not generated by the Python orchestrator (#66): generate_html_report now self-initializes NV_JSON_MODE when unset.

[4.2.4] - 2026-07-04

Fixed

  • E2E smoke test share-lookup false failure (#62): scripts/e2e_smoke_test.sh now includes a minimal report_html part 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_VERSION now derives from the VERSION file at source time (was hardcoded 2.7.0), so report footers, session tool_version, and the exec summary render the correct version. bump_version.sh consistency-checks the fallback pin.

CI

  • release.yml runs the BATS assertion lint (#47), matching ci.yml and the pre-commit hook.

[4.2.0] - [4.2.2]

Added

  • Container image (#54): a single-stage Alpine Dockerfile bundling 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-root netvuln user. Published to a container registry via .gitea/workflows/publish-image.yml (:latest plus :<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_TOKEN are 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_KEY is the canonical license, with identical bash and Python resolution precedence (NV_LICENSE_KEY, NV_API_KEY, CONSULTATION_API_KEY, ~/.netvuln/license.key). Keys parse against nvt_{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.sh and netvuln/license.py query GET /api/license with 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.sh and 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/bash 3.2.

[4.0.0] - [4.0.4]

Added

  • Automated CI versioning (#28): VERSION as the single source of truth, scripts/bump_version.sh (patch/minor/major) atomically updating VERSION, pyproject.toml, and netvuln/__init__.py; release_check.yml enforces the bump on PRs to main; release.yml auto-creates the git tag and release with generated notes on merge.
  • Python quality CI job: python-checks runs pytest plus mypy via venv.

Fixed

  • v4.0.1 - v4.0.4 release-pipeline hardening: workflow_dispatch manual fallback, a fix for a column-0 Python heredoc that broke the release.yml YAML, and a workflow-yaml CI 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 a py.typed marker. pip install -e . provides the netvuln console script. See Python Orchestrator.
  • Pipeline plugin hooks, license soft gate, and progress callbacks (v3.4.0): _run_hooks() fires at phase boundaries; netvuln status --remote lists portal sessions via JWT; netvuln daemon wraps netvuln_daemon_ctl.sh.
  • Parallel module execution (v3.5.0): independent enumeration and report modules run concurrently via ThreadPoolExecutor with 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) and lib/plugin_loader.sh. api_debug.sh portal 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_ID multi-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)

VersionTagHighlights
4.20.0v4.20.0First Community Edition release; posture-steered demo report pipeline (#323)
4.10.0v4.10.0Community Edition export pipeline to the public GitLab mirror (#315)
4.9.0 - 4.9.3v4.9.xDedicated nvt service account and /opt install layout; executable-bit guard; timeout-finalize hardening (#297, #302, #306)
4.8.0 - 4.8.10v4.8.xC2 push_session post-scan regeneration and command dedup; business-tier C2 access; daemon troubleshooting runbook (#239, #243, #246, #281)
4.7.0v4.7.0C2 run_scan post-scan modules; refresh_reports.sh Identity JWT fix (#229, #227)
4.6.0v4.6.0Daemon-uploaded sessions include a generated report; raw-scan capability survives nmap upgrades (#217, #215)
4.5.0v4.5.0Full toolchain install by default; rootless privileged scans; ANSI-clean C2 output (#208, #209, #210)
4.4.0 - 4.4.6v4.4.xPortal session-listing client and hardened refresh; unified stable agent id; daemon status fixes (#145, #193, #194)
4.3.4 - 4.3.10v4.3.xPublic docs sanitization; house style checker; Identity JWT header fix (#109, #129, #147)
4.3.3v4.3.3Docs custom domain + SEO (#101); doc version-drift guard + auto-sync (#102, #104)
4.3.2v4.3.2E2E smoke-test whitespace-strip fix
4.3.1v4.3.1Docs site CI auto-deploy; Portal nav link fix (#96)
4.3.0v4.3.0End-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.4v4.2.4E2E smoke test share round-trip fix (#62); 1036 BATS + 143 client + 436 Python tests
4.2.3v4.2.3Session license metadata + business-tier gating (#46); NV_VERSION from VERSION file (#52)
4.2.0 - 4.2.2v4.2.xContainerized Alpine image published to a container registry (#54); publish + bats-pin hardening
4.1.0v4.1.0Unified license model + online validation; ORC 9.64 framework; BATS || false sweep (#40, #41, #42)
4.0.0 - 4.0.4v4.0.xAutomated CI versioning + auto-tagging; Python quality CI; release-pipeline hardening (#28)
3.3.0 - 3.5.0v3.3-3.5Python orchestrator (full CLI, native scoring/upload/diff, strict mypy); plugin hooks; parallel modules
3.2.0 - 3.2.1v3.2.xCompliance mapping (CIS v8, NIST CSF, PCI-DSS v4.0, SOC 2); network topology visualization
3.1.0v3.1.0Synthetic collections; exception/accept-liability workflow; dual scoring model
3.0.0v3.0.0Persistent scheduling daemon; daemon control CLI; systemd integration
2.8.0 - 2.15.0v2.8-2.15Risk scoring, email security, remediation tracking, alerts, exec summaries, white-labeling, scheduling
2.0 - 2.7.0v2.xMulti-phase recon pipeline, HTML reports, CVE lookup, portal upload, remediation playbook
1.0v1.0.0Initial 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.

Apache-2.0 licensed (appliance subtree proprietary)