Export Nessus scan results via the API, with a reconstruction fallback for trial-mode servers.
Project description
nessus-export
Export Nessus scan results from the
command line via the REST API — with an automatic fallback that reconstructs a
valid .nessus file even when the server's native export is locked (as it is
on Nessus Essentials / trial installations).
Zero dependencies. Pure Python standard library.
Why this exists
Nessus has a perfectly good export API (POST /scans/{id}/export). But on
Nessus Essentials and trial installations, every export format is
license-gated. Ask for one and the server refuses:
{ "error": "Export is not allowed in trial mode. Please purchase a full Nessus license to enable exports." }
That's frustrating, because the scan data itself is not restricted — the
per-scan, per-host, and per-plugin read endpoints (GET /scans/{id},
GET /scans/{id}/hosts/{host}, GET /scans/{id}/hosts/{host}/plugins/{plugin})
return everything: findings, ports/services, severities, CVSS scores, CVEs,
plugin output, remediation text. The export endpoint is gated; the data is not.
nessus-export does the obvious thing:
- Try the native export API first. If your server is licensed, you get the
real, byte-for-byte Nessus export (
.nessus, CSV, PDF, HTML, DB) — no reconstruction, nothing lost. - If the server is in trial mode, it transparently reads the scan data and
reconstructs a spec-compliant
NessusClientData_v2(.nessus) or CSV file itself.
The reconstructed .nessus imports cleanly back into Nessus and into anything
else that consumes the format (parsers, dashboards, DefectDojo, etc.).
Install
pip install nessus-export
Or from source:
git clone https://github.com/setuidloot/nessus-export
cd nessus-export
pip install .
# or run without installing:
python -m nessus_export --help
Requires Python 3.8+. No third-party packages.
Authentication
Generate API keys in Nessus: Settings → My Account → API Keys → Generate.
Provide them any of these ways (checked in order):
- CLI flags:
--access-key/--secret-key - Environment:
ACCESS_KEY/SECRET_KEY(orNESSUS_ACCESS_KEY/NESSUS_SECRET_KEY) - A
.envfile in the working directory (auto-loaded), or--env-file PATH
cp .env.example .env # then edit in your keys
Nessus ships a self-signed TLS certificate, so certificate verification is
off by default. Turn it on with --verify-ssl (optionally --ca-bundle).
Usage
# List scans on the server
nessus-export list
nessus-export list --status completed
nessus-export list --json
# Export one scan by name or id (defaults to .nessus, into the current dir)
nessus-export export myscan
nessus-export export 5 -o results.nessus
# Pick a format
nessus-export export myscan -f csv
nessus-export export myscan -f pdf --chapters vuln_by_host,remediations
# Export several scans into a directory
nessus-export export web-scan db-scan -d ./exports
nessus-export export --all --status completed -d ./exports
# Force behavior
nessus-export export myscan -m native # native API only (fails under trial)
nessus-export export myscan -m reconstruct # skip the API, rebuild locally
Commands
| Command | Purpose |
|---|---|
list |
List scans (--status, --json) |
export |
Export one/several/all scans |
status |
Show server status |
Key export options
| Option | Description |
|---|---|
SCAN… |
One or more scan names or ids |
--all |
Export every scan (combine with --status) |
-f, --format |
nessus (default), csv, pdf, html, db |
-m, --mode |
auto (default), native, reconstruct |
-o, --output |
Output file (single scan) |
-d, --out-dir |
Output directory (multiple scans; filenames from scan names) |
--chapters |
pdf/html sections, comma-separated |
--db-password |
Required for -f db |
-q, --quiet |
Suppress per-step progress |
Export modes
auto(default) — try the native API; if the server reports a trial-mode restriction, fall back to reconstruction (fornessus/csv).native— only use the API. Exits non-zero under trial mode. Use this when you specifically want the licensed, byte-exact export or nothing.reconstruct— skip the API export entirely and rebuild locally. Handy for consistent output across mixed licensed/trial servers.
Formats and modes at a glance
| Format | Native (licensed) | Reconstruction fallback (trial) |
|---|---|---|
nessus |
✅ | ✅ |
csv |
✅ | ✅ |
pdf |
✅ | ❌ (needs a licensed server) |
html |
✅ | ❌ (needs a licensed server) |
db |
✅ | ❌ (needs a licensed server) |
pdf, html, and db are report renderings Nessus builds server-side; there's
no faithful way to reproduce them from the read API, so they require a licensed
server. In auto mode, requesting one on a trial server yields a clear error
rather than a degraded file.
Caveats when reconstructing (trial mode)
When the tool falls back to reconstruction, the findings are complete and faithful — hosts, ports/services, severities, CVSS v2/v3 scores and vectors, CVEs/BIDs/xrefs, synopsis, description, solution, see-also, and plugin output are all carried through. But a reconstructed file is not byte-identical to a licensed export, in these specific ways:
- The
<Policy>block is a stub. A licensed export embeds the full scan policy — every server/plugin preference and the plugin-family selection. Trial mode does not expose that data through the API, so the policy elements are emitted empty. Your findings are intact; the scan configuration metadata is not. HostPropertiesis a subset. It contains what the host-info endpoint returns (IP, FQDN, OS, MAC, start/end time, …) — generally fewer tags than a native export writes.- Plugin output honors the API's truncation. Very large outputs flagged
max_attachments_exceededby the API are carried through exactly as the API returned them (i.e. possibly truncated). - No attachments. Binary attachments some plugins produce are not reassembled.
- CSV columns approximate the native Nessus CSV layout; exact column ordering/quoting may differ slightly.
If any of that matters for your use case, use a licensed server with
-m native. For the common need — "get my findings out in a portable,
importable format" — the reconstructed .nessus does the job.
Supported Nessus versions
Developed and verified against Nessus 10.12.1 (latest at time of writing); expected to work on the Nessus 10.x API generally. It uses only long-standing, stable REST endpoints, so older 8.x/9.x servers will likely work too but are untested. If you run it against another version, a PR updating this section is welcome.
| Nessus version | Status |
|---|---|
| 10.12.1 | ✅ Verified |
| 10.x (other) | 🟡 Expected to work |
| 8.x – 9.x | 🟡 Likely, untested |
How it works
export ──► native API export ──► ready? ──► download (licensed servers)
│
└─ trial-mode 403 ──► read scan + hosts + plugins
└─► serialize NessusClientData_v2 / CSV
The reconstruction walks every host and every plugin finding, so it makes more API calls than a native export — expect it to take longer on large scans.
Library use
from nessus_export.client import NessusClient
from nessus_export.exporter import export_scan
client = NessusClient(url="https://localhost:8834",
access_key="…", secret_key="…")
result = export_scan(client, scan_id=5, fmt="nessus", mode="auto")
open("myscan.nessus", "wb").write(result.content)
print(result.mode) # "native" or "reconstruct"
Security notes
- Never commit your
.env/ API keys..gitignorealready excludes.envand common export artifacts (*.nessus,*.pdf,*.db). - Exported scan results contain sensitive vulnerability data — handle and store them accordingly.
License
MIT — see LICENSE.
Disclaimer
Not affiliated with or endorsed by Tenable, Inc. "Nessus" is a trademark of Tenable, Inc. This tool uses only documented REST endpoints and does not circumvent licensing: it reads data the API already exposes and formats it locally.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file nessus_export-0.1.0.tar.gz.
File metadata
- Download URL: nessus_export-0.1.0.tar.gz
- Upload date:
- Size: 20.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e48d2f4906d3410df73a108ed5027e0b5e7f584d3333439287bea337f1bf8bd9
|
|
| MD5 |
7ebba0c32169d49caea24f33e72dd3b0
|
|
| BLAKE2b-256 |
75ee6bfa05bb938866d40a850cbfc74431191fbb9984bcbf924b78273372143d
|
Provenance
The following attestation bundles were made for nessus_export-0.1.0.tar.gz:
Publisher:
publish.yml on setuidloot/nessus-export
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
nessus_export-0.1.0.tar.gz -
Subject digest:
e48d2f4906d3410df73a108ed5027e0b5e7f584d3333439287bea337f1bf8bd9 - Sigstore transparency entry: 2187398206
- Sigstore integration time:
-
Permalink:
setuidloot/nessus-export@7a868d962fe51263d0691e8a1861765bda42ff84 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/setuidloot
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@7a868d962fe51263d0691e8a1861765bda42ff84 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file nessus_export-0.1.0-py3-none-any.whl.
File metadata
- Download URL: nessus_export-0.1.0-py3-none-any.whl
- Upload date:
- Size: 17.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4539f1bcc18b9c9a9ccc78de5a2303ae60104e2db38b56cc62cee5f15c9fd189
|
|
| MD5 |
98da87de93057d35385e17ab22b2dac8
|
|
| BLAKE2b-256 |
bdc960ea9c177d7c925452bbbf1f352ac9291cc54324b250c37903bfde9249ab
|
Provenance
The following attestation bundles were made for nessus_export-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on setuidloot/nessus-export
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
nessus_export-0.1.0-py3-none-any.whl -
Subject digest:
4539f1bcc18b9c9a9ccc78de5a2303ae60104e2db38b56cc62cee5f15c9fd189 - Sigstore transparency entry: 2187398245
- Sigstore integration time:
-
Permalink:
setuidloot/nessus-export@7a868d962fe51263d0691e8a1861765bda42ff84 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/setuidloot
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@7a868d962fe51263d0691e8a1861765bda42ff84 -
Trigger Event:
workflow_dispatch
-
Statement type: