How SkillSpector's OSV.dev Integration Performs Live CVE Lookups
SkillSpector queries the OSV.dev batch API with built-in caching and graceful fallback mechanisms to deliver real-time CVE detection for Python and JavaScript dependencies without requiring external vulnerability databases.
NVIDIA's SkillSpector performs live vulnerability lookups by integrating directly with the OSV.dev database. The implementation, found primarily in src/skillspector/nodes/analyzers/osv_client.py, enables the supply-chain analyzer to detect security vulnerabilities in PyPI and npm dependencies as part of its static analysis pipeline.
How SkillSpector Performs Live CVE Lookups via OSV.dev
The integration follows a multi-stage pipeline that minimizes network traffic while maximizing detection accuracy. Each stage is implemented in src/skillspector/nodes/analyzers/osv_client.py and orchestrated by the supply-chain analyzer.
Building Package-Level Queries
For each dependency, SkillSpector constructs a JSON query containing the package name, optional version, and ecosystem identifier. The helper function _build_query (around lines 92-96) formats these into OSV-compliant structures:
- PyPI packages: Use the
ECOSYSTEM_PYPIconstant ("PyPI") - npm packages: Use the
ECOSYSTEM_NPMconstant ("npm")
In-Memory Caching Strategy
Before issuing HTTP requests, the client checks an in-process cache keyed by the tuple (name, version, ecosystem). The implementation uses _get_cached and _put_cache (lines 56-80) with a fixed TTL of 3600 seconds (_CACHE_TTL_SECS = 3600). According to the SkillSpector source code, this prevents duplicate lookups for the same package within a single analysis run.
Batch API Requests
All uncached queries are sent in a single POST request to https://api.osv.dev/v1/querybatch (defined as _OSV_BATCH_URL at lines 51-53). The batch approach reduces network overhead compared to individual requests for each dependency.
Vulnerability Detail Fetching
For each vulnerability ID returned by the batch query, SkillSpector issues a GET request to https://api.osv.dev/v1/vulns/<ID>. The _fetch_vuln_details function (lines 86-100) limits processing to the first 10 IDs to avoid latency spikes. It parses the JSON into VulnResult objects containing:
vuln_id: The OSV vulnerability identifiersummary: Human-readable descriptionseverity: Calculated severity levelaliases: Associated CVE numbers
Severity Estimation Without External Dependencies
When OSV returns CVSS vectors but no explicit severity score, SkillSpector uses _estimate_cvss_severity (lines 101-146) to calculate a coarse severity band. As implemented in NVIDIA/SkillSpector, this internal estimation avoids pulling in heavy CVSS libraries while still categorizing vulnerabilities as CRITICAL, HIGH, MEDIUM, or LOW.
Resilient Live CVE Lookup with Fallback Handling
SkillSpector ensures deterministic results even in air-gapped environments or during network failures.
Pre-Flight Connectivity Tests
The is_available() function (lines 81-90) performs a lightweight POST with a dummy query to verify OSV.dev reachability before attempting full batch requests.
Graceful Degradation
If the OSV request fails due to network errors, timeouts, or unavailability, query_batch returns empty result lists. The supply-chain analyzer then falls back to built-in static vulnerability databases (_FALLBACK_VULNERABLE_PYPI and _FALLBACK_VULNERABLE_NPM), ensuring the analysis completes without external dependencies.
Integration with the Supply Chain Analyzer
The src/skillspector/nodes/analyzers/static_patterns_supply_chain.py module orchestrates the OSV integration:
- Dependency extraction: Parses
requirements.txt,pyproject.toml,setup.py,Pipfile, orpackage.json - Batch invocation: Calls
query_batchwith lists of(name, version)tuples and the appropriate ecosystem constant - Finding generation: Creates SC4 findings for each vulnerable package, including the most severe result and formatted advisory IDs via
_format_vuln_ids - Fallback processing: Packages not covered by OSV or when OSV is unavailable are processed by
_sc4_from_fallback
Practical Example: Querying OSV.dev in SkillSpector
You can use the OSV client directly to check specific packages:
from skillspector.nodes.analyzers.osv_client import (
ECOSYSTEM_PYPI,
ECOSYSTEM_NPM,
query_batch,
is_available,
)
# Verify OSV.dev is reachable
if is_available():
packages = [
("requests", "2.28.0"), # PyPI
("lodash", "4.17.20"), # npm
]
# Query for PyPI vulnerabilities
results = query_batch(packages, ECOSYSTEM_PYPI)
for pkg, vulns in zip(packages, results):
name, version = pkg
if not vulns:
print(f"{name} ({version}) – no known CVEs")
continue
print(f"{name} ({version}) – {len(vulns)} CVE(s) found:")
for v in vulns:
print(f" • {v.vuln_id} – {v.summary[:80]} (severity={v.severity})")
else:
print("OSV.dev unreachable – using static fallback")
In the supply-chain analyzer, this logic is invoked automatically during static analysis:
# Inside static_patterns_supply_chain.py
pkg_pairs = [(name, version) for name, version, _ in packages]
osv_results = query_batch(pkg_pairs, ecosystem) # Live lookup
# osv_results is List[List[VulnResult]] used to build findings
Summary
- Batch API Efficiency: SkillSpector queries
https://api.osv.dev/v1/querybatchwith all uncached packages in a single request, minimizing network overhead. - Intelligent Caching: An in-memory cache with a 3600-second TTL prevents redundant lookups for the same
(name, version, ecosystem)tuple during analysis. - Resilient Design: If OSV.dev is unreachable, the system falls back to static vulnerability lists (
_FALLBACK_VULNERABLE_PYPI,_FALLBACK_VULNERABLE_NPM) to ensure consistent results. - Severity Estimation: The
_estimate_cvss_severityfunction calculates severity bands from CVSS vectors without external dependencies. - Integration Points: The
osv_client.pymodule provides the core functionality, whilestatic_patterns_supply_chain.pycoordinates dependency extraction and finding generation. - Test Coverage: Unit tests in
tests/unit/test_osv_client.pyvalidate cache handling and error paths, whiletests/unit/test_patterns_new.pytests the supply-chain integration.
Frequently Asked Questions
How does SkillSpector handle network failures when querying OSV.dev?
SkillSpector implements multiple resilience mechanisms. The is_available() function performs a lightweight connectivity check before batch requests. If the OSV.dev API returns network errors or timeouts, query_batch returns empty lists, triggering the supply-chain analyzer to use built-in static vulnerability databases instead.
What package ecosystems does SkillSpector's OSV.dev integration support?
The integration currently supports PyPI (Python) and npm (JavaScript) packages. These are identified by the ECOSYSTEM_PYPI and ECOSYSTEM_NPM constants in osv_client.py, corresponding to the OSV.dev ecosystem identifiers "PyPI" and "npm".
How does the caching mechanism work in SkillSpector's OSV client?
The client maintains an in-process cache keyed by the tuple (package_name, version, ecosystem). Before sending HTTP requests, _get_cached checks for existing entries with a 3600-second TTL (_CACHE_TTL_SECS). After processing OSV responses, _put_cache stores the list of VulnResult objects for future lookups within the same analysis run.
What is the severity estimation logic when CVSS vectors are present?
When OSV returns CVSS vectors without explicit severity scores, the _estimate_cvss_severity function (lines 101-146) parses the vector string to estimate a coarse severity band. This logic categorizes vulnerabilities as CRITICAL, HIGH, MEDIUM, or LOW without requiring external CVSS calculation libraries, keeping the dependency footprint minimal.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →