How SkillSpector Implements OSV.dev Integration for CVE Lookups

SkillSpector queries the OSV.dev batch API to perform live CVE lookups on Python and JavaScript dependencies, caching results in-memory for one hour and falling back to a static vulnerability database when the service is unreachable.

NVIDIA's SkillSpector leverages OSV.dev integration to provide real-time vulnerability detection for software supply chains. The implementation resides primarily in skillspector/nodes/analyzers/osv_client.py and enables automatic CVE identification for PyPI and npm packages without requiring local vulnerability databases.

Query Generation and Batch API Requests

The OSV.dev client generates package-level queries using the private _build_query helper function. Each query contains the package name, optional version, and ecosystem identifier ("PyPI" or "npm").

Uncached queries are batched into a single HTTPS POST request to https://api.osv.dev/v1/querybatch. The _OSV_BATCH_URL constant defines this endpoint, and the query_batch function orchestrates the request. The response returns a list of vulnerability IDs for each submitted package, which the client then processes individually.

In-Memory Caching Strategy

To minimize network traffic and latency, the client implements an in-process cache with a one-hour TTL (_CACHE_TTL_SECS = 3600). Cache entries are keyed by the tuple (name, version, ecosystem).

The _get_cached function checks for existing entries before initiating network requests, while _put_cache stores newly retrieved results. This design ensures that repeated analysis of the same dependency within a single process run does not trigger redundant API calls.

Vulnerability Detail Retrieval and Severity Parsing

For each vulnerability ID returned by the batch query, the client fetches detailed records using _fetch_vuln_details. To prevent excessive latency, the implementation limits detail requests to the first ten IDs per package.

The function parses OSV.dev responses into VulnResult objects containing vuln_id, summary, severity, and aliases (including CVE numbers). When OSV reports only CVSS vectors without explicit severity ratings, the _estimate_cvss_severity function maps scores to coarse bands: CRITICAL, HIGH, MEDIUM, or LOW.

Graceful Fallback and Offline Support

Before executing batch requests, the is_available() method performs a lightweight connectivity check by sending a dummy query to confirm reachability. If the OSV.dev service is unreachable due to network errors, timeouts, or air-gapped environments, query_batch returns empty result lists.

The supply-chain analyzer (static_patterns_supply_chain.py) detects these empty results and automatically falls back to built-in static vulnerability lists (_FALLBACK_VULNERABLE_PYPI and _FALLBACK_VULNERABLE_NPM). This guarantees deterministic vulnerability detection even without external connectivity.

Integration with Supply-Chain Analysis

The static_patterns_supply_chain.py analyzer orchestrates the OSV.dev integration by extracting dependencies from requirements.txt, pyproject.toml, setup.py, Pipfile, or package.json. It invokes query_batch with the appropriate ecosystem constant (ECOSYSTEM_PYPI or ECOSYSTEM_NPM).

For each package with identified vulnerabilities, the analyzer creates SC4 findings containing the most severe result and a human-readable advisory list via _format_vuln_ids. Packages not covered by OSV.dev or processed during offline mode route through _sc4_from_fallback for static pattern matching.

Code Examples

The following example demonstrates direct usage of the OSV.dev client:

from skillspector.nodes.analyzers.osv_client import (
    ECOSYSTEM_PYPI,
    ECOSYSTEM_NPM,
    query_batch,
    is_available,
)

# Check that the OSV.dev service is reachable

if is_available():
    # Build a list of (package, version) tuples

    packages = [
        ("requests", "2.28.0"),   # PyPI package

        ("lodash", "4.17.20"),    # npm package

    ]

    # Query the OSV.dev batch endpoint for PyPI packages

    results = query_batch(packages, ECOSYSTEM_PYPI)

    # Inspect the returned VulnResult objects

    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 endpoint not reachable – falling back to static data")

Within the supply-chain analyzer, the integration operates automatically:


# Inside static_patterns_supply_chain.py

pkg_pairs = [(name, version) for name, version, _ in packages]
osv_results = query_batch(pkg_pairs, ecosystem)   # live OSV lookup

# Each osv_results entry is a list[VulnResult] used to build SC4 findings

Summary

  • Batch API: The client sends aggregated queries to https://api.osv.dev/v1/querybatch to minimize network overhead.
  • Caching: In-memory caching with 3600-second TTL prevents redundant lookups for repeated dependencies.
  • Severity Estimation: Custom CVSS parsing estimates severity bands without external libraries.
  • Offline Support: Automatic fallback to static vulnerability databases ensures reliability in air-gapped environments.
  • Ecosystem Coverage: Supports both PyPI and npm ecosystems via ECOSYSTEM_PYPI and ECOSYSTEM_NPM constants.

Frequently Asked Questions

How does SkillSpector handle network failures when querying OSV.dev?

The is_available() function performs a lightweight connectivity check before attempting batch requests. If the OSV.dev endpoint is unreachable, query_batch returns empty lists, triggering the supply-chain analyzer to fall back to static vulnerability databases defined in _FALLBACK_VULNERABLE_PYPI and _FALLBACK_VULNERABLE_NPM.

What is the caching mechanism for OSV.dev queries in SkillSpector?

The OSV client maintains an in-process cache keyed by (package_name, version, ecosystem) with a one-hour TTL (_CACHE_TTL_SECS = 3600). The _get_cached and _put_cache helper functions manage cache read/write operations, ensuring that duplicate vulnerability lookups within the same process execution do not generate redundant API traffic.

Which package ecosystems does SkillSpector support for OSV.dev CVE lookups?

SkillSpector supports PyPI and npm ecosystems through the ECOSYSTEM_PYPI and ECOSYSTEM_NPM constants. The supply-chain analyzer automatically extracts dependencies from Python-specific files (requirements.txt, pyproject.toml, setup.py, Pipfile) and JavaScript package.json manifests for vulnerability scanning.

How does SkillSpector determine severity levels for OSV.dev vulnerabilities?

When OSV.dev returns CVSS vectors without explicit severity fields, the _estimate_cvss_severity function parses the vector to calculate a coarse severity band. This mechanism 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →