CVE Scanner
Description
Given a list of package names and versions, query the OSV database for known vulnerabilities.
When to Use
- Security audit of project dependencies
- CI/CD gate to block vulnerable packages
When NOT to Use
- Runtime production scanning (too slow for hot paths)
Inputs
| Name |
Type |
Required |
Description |
| packages |
list |
yes |
List of {"name": str, "version": str, "ecosystem": str} |
Outputs
| Name |
Type |
Description |
| vulnerabilities |
list |
List of CVE findings |
| safe_count |
int |
Number of packages with no known CVEs |
Example
import requests
def scan_packages(packages: list) -> dict:
'''
Uses OSV.dev API — free and no auth required.
'''
vulns = []
for pkg in packages:
resp = requests.post(
"https://api.osv.dev/v1/query",
json={"package": {"name": pkg["name"], "ecosystem": pkg.get("ecosystem", "PyPI")},
"version": pkg["version"]}
)
resp.raise_for_status()
results = resp.json().get("vulns", [])
for v in results:
vulns.append({
"package": pkg["name"],
"version": pkg["version"],
"id": v.get("id"),
"summary": v.get("summary", "No summary"),
"severity": v.get("database_specific", {}).get("severity", "UNKNOWN"),
})
safe = len(packages) - len({v["package"] for v in vulns})
return {"vulnerabilities": vulns, "safe_count": safe}
# packages = [
# {"name": "requests", "version": "2.25.0", "ecosystem": "PyPI"},
# {"name": "flask", "version": "0.12.2", "ecosystem": "PyPI"},
# ]
# report = scan_packages(packages)
# print(f"Found {len(report['vulnerabilities'])} vulnerabilities")