EZ LearnEZ Learn
Courses
EZ Board
Dashboard
All articles
python-for-cyber-securitypythonnessusvulnerability-scanning

Nessus: Vulnerability Scanning from Python

A building inspector works through a checklist of known defects, room by room, noting what fails and how serious it is. Nessus is that inspector for a computer, and its whole inspection can run from one script.

Ashish Revar18 October 20267 min read3 views
1 video lesson 5:29 total
Sign in to track your progress

Video lesson

Nessus is one of the most widely deployed vulnerability scanners in the world. Driven from Python, an entire inspection, launch, wait, read the findings, becomes a handful of method calls instead of a sequence of clicks in a web interface.

Analogy: The building inspector

A building inspector arrives with a long checklist of known defects, cracked beams, faulty wiring, blocked fire exits, and works through it room by room, noting every item that fails and how serious each one is. Nessus is that inspector for a computer: it checks a target against a continuously updated database of known vulnerabilities and reports each finding with a severity score. What makes it powerful from Python is that the whole inspection can be launched, monitored and read back through an API, so it slots into the assembly line.

Tool in focus: the Nessus REST API

Nessus, from Tenable, exposes a REST API that Python's requests library drives directly, with no Nessus-specific package needed. Authentication uses an API access key and secret key pair generated in the Nessus web interface, which replaces a reusable login password on every request.

Python concept: An API key pair, and why not a password

An API key pair is like a hotel keycard rather than the master key. It can be issued, scoped and revoked without changing your actual account password, and if a script leaks it, you cancel that one card rather than your whole identity. This is why automation authenticates with keys, never with a stored login password.

A small client

nessus_client.py

# nessus_client.py
import requests, time
requests.packages.urllib3.disable_warnings()  # Nessus uses a self-signed cert

class NessusClient:
    def __init__(self, base_url, access_key, secret_key):
        self.base_url = base_url.rstrip("/")
        self.headers = {
            "X-ApiKeys": f"accessKey={access_key}; secretKey={secret_key}",
            "Content-Type": "application/json",
        }

    def launch_scan(self, scan_id):
        r = requests.post(f"{self.base_url}/scans/{scan_id}/launch",
                          headers=self.headers, verify=False)
        r.raise_for_status()
        return r.json()["scan_uuid"]

    def scan_status(self, scan_id):
        r = requests.get(f"{self.base_url}/scans/{scan_id}",
                         headers=self.headers, verify=False)
        r.raise_for_status()
        return r.json()["info"]["status"]

    def wait_for_completion(self, scan_id, poll_seconds=15):
        while True:
            status = self.scan_status(scan_id)
            print(f"Scan {scan_id} status: {status}")
            if status == "completed":
                return
            time.sleep(poll_seconds)

Caution: verify=False is a deliberate, narrow exception

verify=False skips certificate verification, reasonable only because a typical Nessus install uses a self-signed certificate on an internal network. An integration reaching Nessus over an untrusted network should install and verify a proper certificate instead of silently disabling the check this way.

wait_for_completion is a small polling loop: ask the status, print it, and either return once the scan is "completed" or sleep and ask again. This is the same shape as a loop you could write around any slow operation with no notification of its own, checked, waited, checked again.

Severity: reading the triage

Nessus reports severity on a five-point scale.

Analogy: The hospital emergency ward

Triage sees the critically injured first and the minor cases wait. Nessus's severity scale works the same way.

LevelSeverityTypical response
4CriticalSame-day attention, especially on an internet-facing host
3HighPatch within the current cycle; do not let it linger
2MediumSchedule for the next maintenance window
1LowFix when convenient; track so it is not forgotten
0InfoNo action; context for the analyst

Turning a list of findings into a triage summary

nessus_results.py

# nessus_results.py
def get_vulnerabilities(client, scan_id):
    r = requests.get(f"{client.base_url}/scans/{scan_id}",
                     headers=client.headers, verify=False)
    r.raise_for_status()
    return r.json()["vulnerabilities"]

def summarise_by_severity(vulnerabilities):
    names = {4: "Critical", 3: "High", 2: "Medium", 1: "Low", 0: "Info"}
    counts = {name: 0 for name in names.values()}
    for v in vulnerabilities:
        counts[names.get(v["severity"], "Info")] += 1
    return counts

nessus_client = NessusClient("https://127.0.0.1:8834", "access-key", "secret-key")
nessus_client.wait_for_completion(scan_id=42)
vulns = get_vulnerabilities(nessus_client, scan_id=42)
print(summarise_by_severity(vulns))

The get_vulnerabilities() call needs a live Nessus server, which this course cannot ship, so it has not been run against a real one here. summarise_by_severity() itself needs nothing but a list of dictionaries with a "severity" key, so it is fully testable on its own with made-up findings shaped like the real thing:

Sample output, summarise_by_severity() run against 68 synthetic findings (2 critical, 5 high, 13 medium, 7 low, 41 info)

{'Critical': 2, 'High': 5, 'Medium': 13, 'Low': 7, 'Info': 41}

That dictionary, two critical findings demanding same-day attention against forty-one informational items that can wait, is the whole triage summary. A dashboard reads it directly, which is the whole point of the assembly line: no one has to read sixty-eight rows to know where to look first.

Try it yourself: See the pure half run on your own machine

You do not need a Nessus server to try summarise_by_severity() yourself. Build a list of dictionaries with a severity key set to any mix of 0 to 4, call the function, and check the counts add up to the length of your list. This is the testable half of almost every integration in this unit: the logic that shapes data, separate from the network call that fetches it.

Check your understanding

Question 1: Why is an API key pair preferred over a reusable username and password for a script? Use the hotel-keycard idea in your answer.

A hotel keycard can be issued for one stay, scoped to one room, and cancelled without changing the hotel's master lock. An API key pair works the same way: it can be issued for one script's purpose, scoped to what that script needs, and revoked on its own if it leaks, without having to change the account's actual login password everywhere else it is used.

Question 2: What does wait_for_completion() actually do, and why does it need a sleep between checks?

It repeatedly asks the Nessus server for the scan's status and returns once that status is "completed". It sleeps between checks so it does not hammer the server with requests many times a second while the scan, which can take minutes, is still running.

Question 3: Why is summarise_by_severity() testable without a running Nessus server, while get_vulnerabilities() is not?

summarise_by_severity() only operates on a list of dictionaries already in memory; it never talks to a network at all. get_vulnerabilities() makes an HTTP request to a live Nessus server and needs one running and reachable to produce any result.

Key takeaway

Nessus is driven entirely through its REST API, authenticated with a revocable key pair rather than a password, and polled until a scan completes. Its severity scale reads like hospital triage, and summarising findings by severity turns a long list into the one number that actually decides what gets fixed first.

Assessments

Unit Assessment

Integrating Cyber Security Tools with Python

20 questions30 minPass: 60%

Start exam →

Comprehensive Assessment

Python for Cyber Security: Complete Assessment

100 questions120 minPass: 60%

Start final exam →

Related to this topic

Continue learning

Reference material

Cheatsheet

Python for Cyber Security — Cheatsheet

v1.0

Open resource

MCQ Bank

Python for Cyber Security — MCQ Bank

v1.0

Open resource

Question Bank

Python for Cyber Security — Question Bank

v1.0

Open resource

eBook

Python for Cyber Security — eBook

v1.0

Open resource

Discussion

Loading comments…
More articlesTest your knowledge
EZ MentorAI · Free

Nessus: Vulnerability Scanning from Python

Hi! I'm EZ Mentor

Your AI tutor for
Nessus: Vulnerability Scanning from Python

Sign in to ask, it's free.

EZ Mentor is AI-powered · Answers may not be perfect · 10 free questions / day

EZ LearnEZ Learn

Structured learning across Reverse Engineering, Cloud Security, and Research Methodology, plus games and practice tools in EZ Arena. Free, and open to anyone.

EZ Learn

  • Courses
  • EZ Articles
  • EZ Watch
  • EZ Talks
  • EZ Bytes
  • Cyber Hygiene

EZ Library

  • All Resources
  • eBooks & PDFs
  • Question Banks
  • MCQ Banks
  • Cheatsheets

EZ Exams

  • All Exams
  • REMA
  • Cloud Security
  • Research Methodology
  • Python for Cyber Security
  • Cyber Law & IPR
  • Community
  • EZ Board

EZ Arena

  • EZ Games
  • Live Quiz
  • ML Challenges
  • दिशा - Hygiene
  • सजग - Awareness
  • अभ्यास - Practice

Platform

  • About
  • Contact
  • Terms of Use
  • Disclaimer
  • Verify Certificate
  • Events

© 2026 EZ Learn by EpochZero. Educational content for learning purposes.

Platform Lead: Ashish Revar