Converting NVD CVEs for open source software to OSV
Further context at Introducing broad C/C++ vulnerability management support
See run_cve_to_osv_generation.sh for how this is invoked in Production.
To see it in action on a single CVE:
CVE=CVE-2024-3094
git clone --recurse-submodules https://github.com/google/osv.dev
cd osv.dev/vulnfeeds
mkdir /tmp/nvd /tmp/nvd2osv
(cd test_data && ./download_specific_cves $CVE)
mv test_data/nvdcve-2.0/${CVE}.json /tmp/nvd
gcloud storage cp "gs://osv-test-cve-osv-conversion/cpe_repos/cpe_product_to_repo.json" "/tmp"
go run cmd/nvd-cve-osv/main.go \
--cpe_repos "/tmp/cpe_product_to_repo.json" \
--nvd_json "/tmp/nvd/${CVE}.json" \
--out_dir "/tmp/nvd2osv"
cat /tmp/nvd2osv/*/*/${CVE}.json
Conversion metric retrieval
This extracts the per-year metrics from the logs and presents them as a percentage over successful conversions from ones considered to be in scope (having a viable Git repository associated with them by CPE or by presence in a reference URL).
This requires at least these IAM roles:
For more information, see:
$ gcloud --project oss-vdb logging read --freshness=12h --format=json 'logName="projects/oss-vdb/logs/nvd-cve-osv" "Metrics:"' | jq -r '. | map(.textPayload | gsub("[\\n]"; "")) | .[]' | awk '{
match($1, /nvdcve-2\.0-(....)\.json/, year);
match($5, /CVEsForKnownRepos:([0-9]+)/, cves_in_scope);
match($6, /OSVRecordsGenerated:([0-9]+)/, osvs);
print year[1], 100*osvs[1]/cves_in_scope[1]
}' | tail -n $[$(date +%Y) - 2016 + 1]
2016 81.6214
2017 77.1155
2018 64.1689
2019 71.334
2020 73.4837
2021 74.2835
2022 75.2699
2023 73.034
2024 52.2844