Introduction
Recently someone asked:
Is there a way to fetch CVE (vulnerability) data for platforms like Cisco, Palo Alto, and Fortinet in a programmatic way, so we can integrate it into a solution we’re building?
The short answer: yes—and one of the best ways to do this is through the NIST API. The next question was how to use Python to access and work with that data.
In this short guide, we’ll show you how to interface with the NIST National Vulnerability Database (NVD) using a Python library called nvdlib
. If you're working in security automation, vulnerability management, or just want to explore CVE data as part of your network security workflow, this will give you a clean, Pythonic way to query and work with vulnerability data.
Here’s what we’ll cover:
- What is NIST?
- What are CVEs?
- An intro to the NIST APIs
- What is
nvdlib
? - Code examples using
nvdlib
What is NIST?
NIST (National Institute of Standards and Technology) is a U.S. government agency that provides standards, guidelines, and tools to help secure systems and information. One of their key projects in cybersecurity is the National Vulnerability Database (NVD)—a central repository of known security vulnerabilities.
What are CVEs?
CVEs (Common Vulnerabilities and Exposures) are publicly disclosed cybersecurity vulnerabilities. Each CVE is assigned a unique identifier like:
CVE-2023-12345
Each record includes metadata such as severity (via CVSS), affected products, and descriptions. Think of CVEs as standardized labels for security flaws.
What is the NIST API?
NIST exposes an API that allows developers to:
- Search for CVEs by keyword, product, vendor
- Filter CVEs by date, severity, or other metadata
- Retrieve vulnerability feeds in JSON
While powerful, the raw API can be a bit of a pain to work with directly—especially if you’re working in Python.
What is nvdlib?
nvdlib
is a Python wrapper around the NIST NVD API. It abstracts away all the low-level HTTP stuff and gives you a clean, Pythonic interface to query and filter vulnerability data.
pip install nvdlib
Getting Started with nvdlib
Here are a few quick examples to get you started.
Search CVEs by Keyword
import nvdlib
# Search for CVEs containing "Fortinet"
results = nvdlib.searchCVE(keywordSearch='Fortinet')
# Print the results
for cve in results:
print(f"{cve.id} - {cve.descriptions[0].value}")
# Output:
# CVE-2023-33302 - A buffer copy without checking size of input ('classic buffer overflow') in Fortinet FortiMail webmail and administrative interface version 6.4.0 through 6.4.4 and before 6.2.6 and FortiNDR administrative interface version 7.2.0 and before 7.1.0 allows an authenticated attacker with regular webmail access to trigger a buffer overflow and to possibly execute unauthorized code or commands via specifically crafted HTTP requests.
# CVE-2023-40714 - A relative path traversal in Fortinet FortiSIEM versions 7.0.0, 6.7.0 through 6.7.2, 6.6.0 through 6.6.3, 6.5.1, 6.5.0 allows attacker to escalate privilege via uploading certain GUI elements
# ...
Filter CVEs by Severity (e.g., Critical)
import nvdlib
# Retrieve critical CVEs for a specific product and severity
results = nvdlib.searchCVE(keywordSearch='Fortinet', cvssV3Severity='CRITICAL')
# Print the results
for cve in results:
print(f"{cve.id}: {cve.score[2]} - {cve.descriptions[0].value}")
# Output:
# CVE-2016-1909: CRITICAL - Fortinet FortiAnalyzer before 5.0.12 and 5.2.x before 5.2.5; FortiSwitch 3.3.x before 3.3.3; FortiCache 3.0.x before 3.0.8; and FortiOS 4.1.x before 4.1.11, 4.2.x before 4.2.16, 4.3.x before 4.3.17 and 5.0.x before 5.0.8 have a hardcoded passphrase for the Fortimanager_Access account, which allows remote attackers to obtain administrative access via an SSH session.
# ...
Search by NOS Version
import nvdlib
# Retrieve critical CVEs for a specific product, severity, and version range
results = nvdlib.searchCVE(
keywordSearch='Fortinet',
cvssV3Severity='CRITICAL',
virtualMatchString='cpe:2.3:o:fortinet:fortios:*:*:*:*:*:*:*:*',
versionStart='6.0.0',
versionStartType='including',
versionEnd='6.4.10',
versionEndType='including',
limit=10
)
# Print the results
for cve in results:
print(f"{cve.id}: {cve.score[2]} - {cve.descriptions[0].value}")
# Output:
# CVE-2018-13379: CRITICAL - An Improper Limitation of a Pathname to a Restricted Directory ("Path Traversal") in Fortinet FortiOS 6.0.0 to 6.0.4, 5.6.3 to 5.6.7 and 5.4.6 to 5.4.12 and FortiProxy 2.0.0, 1.2.0 to 1.2.8, 1.1.0 to 1.1.6, 1.0.0 to 1.0.7 under SSL VPN web portal allows an unauthenticated attacker to download system files via special crafted HTTP resource requests.
# ...
Wrap-Up
I hope you found this short post helpful for getting started with the NIST CVE database using nvdlib
.
This kind of integration can be especially useful when paired with a source of truth like NetBox—whether you're looking to track vulnerabilities across your infrastructure, highlight risks linked to specific devices, or feed CVE data into internal tools.
Resources
- GitHub: https://github.com/Vehemont/nvdlib
- NIST API Docs: https://nvd.nist.gov/developers/vulnerabilities