Vulnerability information
NuGet client, starting from version 6.7, can download known package vulnerability information to use in scenarios such as checking packages during restore operations. While the package metadata resource also contains known vulnerability information, if an app needs to check a large number of packages for known vulnerabilities, it's much faster to download a file of known vulnerabilities and lookup locally, rather than making a large number of HTTP requests. For example, this enables NuGet Restore to quickly check restored packages for known vulnerabilities, which historically never downloaded package details from the package metadata resource.
The API consists of at least two files, the vulnerability index and one or more vulnerability page files. Known vulnerability data can be partitioned into multiple files, and the vulnerability index provides clients with information needed to cache files, and update the cache, efficiently.
The resource used for building this URL is the VulnerabilityInfo
resource found in the service index.
Suggested partitioning strategy
The pages listed in the vulnerability index should ideally be optimized to maximize caching, and therefore minimize updates to large files. This will allow clients to minimize the frequency it needs to download updates.
A suggested strategy for vulnerability data partitioning is to have two pages, base.json
and updates.json
.
The base.json
file is updated periodically (for example once a month), and contains all known vulnerabilities at the time the file is regenerated.
The updates.json
file should contain any new advisories published since base.json
was last regenerated.
This will allow clients to download the large base.json
infrequently, while the frequently changing updates.json
file is always relatively small.
NuGet clients combine the data from multiple files additively, and may load the files in any order.
The data file schema does not allow for modification or redaction of known vulnerability from another file.
Therefore if a server's vulnerability data source (for example the GitHub Advisories Database) modifies an existing advisory, the NuGet server must modify the page that the vulnerability information was previously reported.
One way to achieve this with the suggested partition scheme is to treat all vulnerability modifications and deletions as a trigger to regenerate the complete base.json
file, and empty updates.json
.
Versioning
The following @type
values are used:
@type value | Notes |
---|---|
VulnerabilityInfo/6.7.0 | The initial release |
Vulnerability index
The vulnerability index is a JSON array of objects with the following properties:
Name | Type | Required | Notes |
---|---|---|---|
@name | string | yes | A short name for the file, used as a cache key. |
@id | string | yes | The full (absolute) URL to a vulnerability data file. |
@updated | string | yes | An ISO 8601 string representing the date and time the file was last updated, ideally with the UTC timezone. |
comment | string | no | A optional descriptive string. |
The following restrictions apply:
- The index must be an array of objects with between 1 and 16 items.
If the server does not have any vulnerability data (zero pages), then must remove the
VulnerabilityInfo
resource from theServiceIndex
. @name
must be unique within the index, must be between 1 and 32 characters long, and can only use the charactersA
toZ
,a
toz
,0
to9
,-
, or_
.@id
must be an absolute URL, not a relative URL.
Vulnerability page
Vulnerability page files are a JSON object used as a dictionary. Property keys are the lower-case package id and property values are an array of the following object with the following properties:
Name | Type | Required | Notes |
---|---|---|---|
severity | integer | yes | 0 means low, 1 means medium, 2 means high, 3 means critical. |
url | string | yes | URL where users can get more information about the vulnerability. |
versions | string | yes | The version range that is vulnerable, using NuGet's version range syntax. |
Package IDs (the root object's keys) must be lowercased with String.ToLowerInvariant
.
The list of known vulnerabilities for a package should be sorted in descending order of the max version of the version range, followed by descending version of the min version, followed by the ascending order of the URL. Ranges with null min or max versions (unbounded) in a version range should be sorted to before non-null (bounded) versions.
An empty page, one that does not provide any known vulnerabilities, must be an empty JSON array ([]
).
Samples
Here is a sample of a vulnerability index:
[
{
"@name": "base",
"@id": "https://nuget.contoso.com/v3/vulnerabilities/3bb6b300-2f74-45bc-af06-746fd21c024b.json",
"@updated": "2023-06-01T06:14:58.4159909Z",
"comment": "The base data for vulnerability update periodically"
},
{
"@name": "update",
"@id": "https://nuget.contoso.com/v3/vulnerabilities/ffd572cd-33f3-4372-8714-a9cab2e86b45.json",
"@updated": "2023-06-14T11:35:30.3155764Z",
"comment": "The patch data for the vulnerability. Contains all the vulnerabilities since base was last updated."
}
]
Here is a sample of a vulnerability data file:
{
"contoso.library": [
{
"url": "https://cve.contoso.com/advisories/1",
"severity": 1,
"versions": "(, 2.0.0)"
},
{
"url": "https://cve.contoso.com/advisories/2",
"severity": 2,
"versions": "(1.0.0, 2.0.0)"
}
],
"contoso.utilities": [
{
"url": "https://cve.contoso.com/advisories/3",
"severity": 3,
"versions": "(, 1.0.0)"
}
]
}