How SkillSpector Integrates with OSV.dev for Vulnerability Lookups
SkillSpector performs batch vulnerability lookups against the OSV.dev database using HTTP POST requests to identify security risks in Python and JavaScript dependencies, with built-in caching and static fallback lists for offline operation.
SkillSpector, NVIDIA's skill security analysis framework, integrates with the Open Source Vulnerability (OSV) database to detect vulnerable third-party dependencies. The SkillSpector OSV.dev integration enables automated security scanning of requirements.txt and package.json files by querying the public OSV API with batched requests. This implementation combines live vulnerability data with local caching and offline fallback mechanisms to ensure reliable detection across network conditions.
Batch Query Architecture
The OSV client implements a two-stage lookup process that minimizes API calls while retrieving comprehensive vulnerability data.
Building the Batch Request
In src/skillspector/nodes/analyzers/osv_client.py, the _build_query() method (lines 92-96) constructs the JSON payload containing all package names and versions from a dependency file. The query_batch() function (lines 122-135) sends this payload via httpx in a single HTTP POST request to https://api.osv.dev/v1/querybatch.
Fetching Detailed Vulnerability Data
For each vulnerability ID returned by the batch query, _fetch_vuln_details() (lines 86-96) executes a secondary GET request to https://api.osv.dev/v1/vulns/<ID>. This retrieves the full advisory including severity scores, aliases, and human-readable summaries.
Caching and Offline Fallback
The integration prioritizes performance and reliability through aggressive caching and static fallback databases.
In-Memory Caching Strategy
Results are cached in the _cache dictionary (lines 57-61) keyed by the tuple (name, version, ecosystem) with a one-hour TTL (_CACHE_TTL_SECS). This prevents redundant API calls when analyzing multiple skills with overlapping dependencies.
Static Fallback Databases
When the OSV API is unreachable or returns no data, the analyzer falls back to curated static lists defined in src/skillspector/nodes/analyzers/static_patterns_supply_chain.py. The variables _FALLBACK_VULNERABLE_PYPI and _FALLBACK_VULNERABLE_NPM (lines 104-132) contain known vulnerable packages for offline detection in air-gapped environments.
Severity Normalization
Vulnerability severity is standardized through a multi-step extraction process. The _severity_from_vuln() method (lines 49-57) prioritizes GHSA severity ratings, followed by ecosystem-specific scores, then CVSS vectors. The helper _osv_severity_to_app() (lines 60-68) maps these values to the internal Severity enum (CRITICAL, HIGH, MEDIUM, or LOW).
Integration with Supply-Chain Analysis
The static_patterns_supply_chain analyzer orchestrates the vulnerability detection workflow. The _sc4_from_osv() function (lines 88-108) invokes query_batch() and converts results into AnalyzerFinding objects containing package identifiers, advisory counts, and formatted summaries via _format_vuln_ids(). Uncovered packages pass to _sc4_from_fallback() (lines 136-176) for static pattern matching.
Implementation Examples
Run a manual OSV lookup from a Python REPL:
from skillspector.nodes.analyzers.osv_client import query_batch, ECOSYSTEM_PYPI
# Example packages extracted from a requirements.txt file
packages = [("requests", "2.28.1"), ("django", None)]
# Perform the batch lookup
results = query_batch(packages, ECOSYSTEM_PYPI)
for pkg, vulns in zip(packages, results):
name, version = pkg
print(f"{name}{'==' + version if version else ''}:")
for v in vulns:
print(f" - {v.vuln_id} [{v.severity}] {v.summary}")
Integrate OSV results into the supply-chain analyzer:
def _sc4_from_osv(
packages: list[tuple[str, str | None, int]],
ecosystem: str,
file_path: str,
tag: list[str],
) -> tuple[list[AnalyzerFinding], set[str]]:
# Build (name, version) tuples for the OSV client
pkg_pairs = [(name, version) for name, version, _ in packages]
# Query OSV.dev (live lookup)
osv_results = query_batch(pkg_pairs, ecosystem)
# Convert OSV results → AnalyzerFinding objects
...
Summary
- SkillSpector uses the OSV.dev batch API (
/v1/querybatch) to query multiple dependencies in a single HTTP request. - The
osv_client.pymodule implements caching with a one-hour TTL and static fallback lists for offline operation. - Severity scores normalize to four levels (CRITICAL, HIGH, MEDIUM, or LOW) from GHSA, ecosystem, or CVSS sources.
- The supply-chain analyzer (
static_patterns_supply_chain.py) coordinates live OSV queries with static pattern matching via_sc4_from_osv()and_sc4_from_fallback().
Frequently Asked Questions
What API endpoint does SkillSpector use for OSV queries?
SkillSpector sends POST requests to https://api.osv.dev/v1/querybatch for batch vulnerability lookups and GET requests to https://api.osv.dev/v1/vulns/<ID> for detailed advisory information, as implemented in osv_client.py.
How does SkillSpector handle network failures during vulnerability scanning?
When the OSV API is unreachable, the analyzer automatically falls back to static vulnerability lists (_FALLBACK_VULNERABLE_PYPI and _FALLBACK_VULNERABLE_NPM) defined in static_patterns_supply_chain.py, ensuring security checks continue in air-gapped environments.
What is the cache duration for OSV vulnerability lookups?
The OSV client maintains an in-memory cache keyed by package name, version, and ecosystem with a TTL of one hour (_CACHE_TTL_SECS), preventing redundant API calls during repeated scans.
Which ecosystems does SkillSpector support for OSV vulnerability detection?
The implementation supports PyPI (Python) and npm (JavaScript) ecosystems through the ECOSYSTEM_PYPI constant and corresponding fallback lists, as defined in the OSV client and static patterns modules.
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 →