NVD officially provides APIs for CPE and CVE, while both are set with rate limit.
To support high-volume query, go-nvd
supports command to dump data from NVD to self-owned database and run API server on top of that to provide same API spec and part of parameters as NVD.
- Available database:
mongo
API DB (nvd)
┌────────────────┐ ┌───────────┐
http │ ┌────────────┐ │ │ ┌───────┐ │ nvdetl
req ———▶ │ │ (get) cve │-│- - - —▶ │ │ cve │ │ (command) ┌───────┐
│ └────────────┘ │ │ └───────┘ │ ◀────────── │ NVD │
http │ ┌────────────┐ │ │ ┌───────┐ │ └───────┘
rsp ◀─── │ │ (get) cpe │-│- - - —▶ │ │ cpe │ │
│ └────────────┘ │ │ └───────┘ │
└────────────────┘ └───────────┘
- - —▶ read
—————▶ write / data flow
To try with docker, check playground
There are some difference between go-nvd and offical nvd:
- Only support partial query parameters:
- cve:
cveId
,cpeName
,keywordSearch
(keywordExactMatch
),resultsPerPage
(default:2000
) andstartIndex
- cpe:
cpeName
,cpeMatchString
,keywordSearch
(keywordExactMatch
),resultsPerPage
(default:10000
) andstartIndex
- cve:
- It's mandatory to provide one of the query in query string, while offical nvd api return all cve/cpe if not given.
- cve: one of
cveId
,cpeName
,keywordSearch
should be given, else raising400
error - cpe: one of
cpeName
,cpeMatchString
,keywordSearch
should be given, else raising400
error
- cve: one of
- Different logic to match the version of CPE, which might causing different results.
- E.g., for
CVE-2003-0132
, it should be returned when query with version betweenapache:http_server:2.0.0
andapache:http_server:2.0.44
. However, should it match with partial versionapache:http_server:2.0
? NVD does not return while this repo regards2.0
as2.0.0
andCVE-2003-0132
will be returned.
Actually, partial version should not be expected as valid input, whlie there are still softwares with version format:
<major>.<minor>
instead of<major>.<minor>.<patch>
. - E.g., for
check db.md for the details
check nvd.md for the details
nvdetl
for how to use command to dump data to database- ETL from the start describes how to dump all the data with the correct order from NVD to database
readiness endpoint: nvd/v1/readiness
This API mimics the NVD CVE API, which implements the logic for cveId
, cpeName
, keywordSearch
(keywordExactMatch
),resultsPerPage
(default:2000
) and startIndex
in query string, and the response is also the same.
To get CVEs by cveId
, cpeName
or keywordSearch
(keywordExactMatch
). E.g.,
- Query with
cveId = CVE-2006-3240
=>/nvd/v1/cve?cveId=CVE-2006-3240
- Query with
cpeName = cpe:2.3:a:dotproject:dotproject:*:*:*:*:*:*:*:*
=>/nvd/v1/cve?cpeName=cpe:2.3:a:dotproject:dotproject:*:*:*:*:*:*:*:*
- Query with
keywordSearch = Java Oracle
=>/nvd/v1/cve?keywordSearch=Java Oracle
- Query with
keywordExactMatch
=>/nvd/v1/cve?keywordSearch=Java Oracle&keywordExactMatch
- Query with
200
found, which is same format as NVD
{
"resultsPerPage": 1,
"startIndex": 0,
"totalResults": 1,
"format": "NVD_CVE",
"version": "2.0",
"timestamp": "2022-12-28T15:01:34.530",
"vulnerabilities": [...], // CVE list
}
200
not found
{
"resultsPerPage": 0,
"startIndex": 0,
"totalResults": 0,
"format": "NVD_CVE",
"version": "2.0",
"timestamp": "2022-12-28T15:01:34.530",
"vulnerabilities": [], // CVE list
}
This API mimics the NVD CPE API, which implements the logic for cpeName
, cpeMatchString
, keywordSearch
(keywordExactMatch
),resultsPerPage
(default:10000
) and startIndex
in query string, and the response is also the same.
To get CPEs by cpeName
, cpeMatchString
, or keywordSearch
(keywordExactMatch
). E.g.,
- Query with
cpeName = cpe:2.3:a:dotproject:dotproject:*:*:*:*:*:*:*:*
=>/nvd/v1/cpe?cpeName=cpe:2.3:a:dotproject:dotproject:*:*:*:*:*:*:*:*
- Query with
cpeMatchString = cpe:2.3:o:microsoft:windows_10
=>/nvd/v1/cpe?cpeMatchString=cpe:2.3:o:microsoft:windows_10
- Query with
keywordSearch = Java Oracle
=>/nvd/v1/cpe?keywordSearch=Java Oracle
- Query with
keywordExactMatch
=>/nvd/v1/cpe?keywordSearch=Java Oracle&keywordExactMatch
- Query with
200
found, which is same format as NVD
{
"resultsPerPage": 1,
"startIndex": 0,
"totalResults": 1,
"format": "NVD_CPE",
"version": "2.0",
"timestamp": "2022-12-28T15:01:34.530",
"products": [...], // CPE list
}
200
not found
{
"resultsPerPage": 0,
"startIndex": 0,
"totalResults": 0,
"format": "NVD_CPE",
"version": "2.0",
"timestamp": "2022-12-28T15:01:34.530",
"products": [], // CPE list
}
http_request_total{api=...,code=...}
(counter) The amount of requests per HTTP status codeapi
includes/nvd/v1/cve
/nvd/v1/cpe
http_request_duration_seconds
(histogram) A histogram of latencies for requests
get_request_total{api=...,status=...}
(counter) The amount of requests to get scan report and statusapi
includes/cve
/cpe
status
includesfound
not_found
error
$ cd go-nvd
$ GOOS=linux go build -o service/build/bin/ ./...
$ cd service/build
$ docker build -t nvd-tools .
check Endpoints for all the exposing ports.
$ cd service/test
$ docker-compose -f docker-compose-mongo.yaml up -d
check Usage for the usage of nvdetl
command
-apikey
: query NVD with API Key if given-wait
: sleep seconds between each API request to NVD
# dump CVEs with lastModified between 2023-03-01 and 2023-03-02
$ docker run --rm --network go-nvd --entrypoint nvdetl nvd-tools -db-type mongo -db-user admin -db-pwd admin -db-endpoint mongo:27017 -sdate 2023-03-01 -edate 2023-03-02 -batch 100 -type cve
# dump CPEs with lastModified between 2023-03-01 and 2023-03-02
$ docker run --rm --network go-nvd --entrypoint nvdetl nvd-tools -db-type mongo -db-user admin -db-pwd admin -db-endpoint mongo:27017 -sdate 2023-03-01 -edate 2023-03-02 -batch 100 -type cpe
- CVE API
$ curl 'http://localhost:8080/nvd/v1/cve?cveId=CVE-2022-26579'
- CPE API
$ curl 'http://localhost:8080/nvd/v1/cpe?cpeName=cpe:2.3:a:luya:yii-helpers:1.0.0:*:*:*:*:*:*:*'