From 1d62adf667549a6424aa9c5c1fa775ac1d775a82 Mon Sep 17 00:00:00 2001 From: Oliver Chang Date: Thu, 5 Aug 2021 16:41:07 +1000 Subject: [PATCH 01/22] Support multiple packages in one entry. - Rename "affects" to "affected", and make it a list of objects. - Move "package", "ecosystem_specific", "database_specific" to "affected". - Add "routines" and "platforms" to "affected" as well. --- schema.md | 398 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 218 insertions(+), 180 deletions(-) diff --git a/schema.md b/schema.md index 9101ae64..9ab0b5e3 100644 --- a/schema.md +++ b/schema.md @@ -1,6 +1,6 @@ # Open Source Vulnerability format -**Version 0.7.1 (June 30, 2021)** +**Version 0.8 (August 5, 2021)** Original authors: - Oliver Chang (ochang@google.com) @@ -56,28 +56,30 @@ contain UTF-8 text. "withdrawn": string, "aliases": [ string ], "related": [ string ], - "package": { - "ecosystem": string, - "name": string, - "purl": string, - }, "summary": string, "details": string, - "affects": { + "affected": [ { + "package": { + "ecosystem": string, + "name": string, + "purl": string, + }, "ranges": [ { "type": string, "repo": string, "introduced": string, "fixed": string } ], - "versions": [ string ] - }, + "versions": [ string ], + "platforms": [ string ], + "routines": [ string ], + "ecosystem_specific": { see description }, + "database_specific": { see description }, + } ], "references": [ { "type": string, "url": string } ], - "ecosystem_specific": { see description }, - "database_specific": { see description }, } ``` @@ -158,11 +160,59 @@ same database, the duplicate entry could be written using only the `id`, The `related` field gives a list of IDs of closely related vulnerabilities, such as the same problem in alternate ecosystems. -### package field +### summary, details fields + +The `summary` field gives a one-line, English textual summary of the +vulnerability. It is recommended that this field be kept short, on the order of +no more than 120 characters. + +The `details` field gives additional English textual details about the +vulnerability. The field is plain text. Newline characters must be considered +line breaks when displaying the text, but the display need not use a fixed-width +font, and the text should not assume one. + +The `summary` field is plain text. + +The `details` field is CommonMark markdown (a subset of GitHub-Flavored +Markdown). Display code may at its discretion sanitize the input further, such +as stripping raw HTML and links that do not start with http:// or https://. +Databases are encouraged not to include those in the first place. (The goal is +to balance flexibility of presentation with not exposing vulnerability database +display sites to unnecessary vulnerabilities.) + +### affected fields + +The `affected` field is a JSON array containing objects that describes the +affected packages versions, meaning those that contain the vulnerability. -The `package` field is a JSON object identifying the affected code library or -command provided by the package. The object itself has two required fields, -`ecosystem` and `name`, and an optional `purl` field. +Within each object in the `affected` array, the `package` field identifies the +package containing the vulnerability. + +The `versions` field can enumerate a specific set of affected versions, and the +`ranges` field can list ranges of affected versions, under a given defined +ordering. A version is considered affected if it lies within any one of the +ranges or is listed in the versions list. + +The `versions` list should - with one exception - always be present, to allow +software to answer the question "is this specific version affected?" without +having to contain code specific to every different ecosystem. The one exception +is if the affected versions are valid SemVer 2.0 versions which can be +accurately summarized by one or more non-overlapping SemVer ranges. In that +case, the SemVer ranges can be listed instead, in entries in the `ranges` field +with type `SEMVER` (see below). In this case, the SemVer ranges act as a kind of +compact form of a larger `versions` list. Ecosystems that do not use SemVer +identifiers or that order versions differently from SemVer must include the +enumerated `versions` list, although they can also add ranges of type +`ECOSYSTEM` for additional context. + +In short, each object in the `affected` array must contain either a non-empty +`versions` list or at least one range in the `ranges` list of type `SEMVER`. + +#### affected[].package field + +The `affected` object's `package` field is a JSON object identifying the +affected code library or command provided by the package. The object itself has +two required fields, `ecosystem` and `name`, and an optional `purl` field. The `ecosystem` identifies the overall library ecosystem. It must be one of the strings in the table below. The `name` field is a string identifying the library @@ -174,7 +224,7 @@ The `purl` field is a string following the identifies the package. This field is optional but recommended. Different ecosystems can define the same names; they identify different -packages. For example, these denote different libraries with different sets of +packages. For example, these denote different libraries with different sets of versions and different potential vulnerabilities: `{"ecosystem": "npm", "name": "zlib"}` @@ -205,68 +255,15 @@ It is permitted for a database name (the DB prefix in the `id` field) and an ecosystem name to be the same, provided they have the same owner who can make decisions about the meaning of the `ecosystem_specific` field (see below). -If the same root mistake causes a vulnerability in multiple ecosystems, each -ecosystem’s instance of the vulnerability would have its own separate -vulnerability entry, one per package.ecosystem that needs to be specified. This -matches existing databases like GHSA. For example CVE 2019-8331, a bug in -Bootstrap JavaScript files, is recorded as both -https://github.com/advisories/GHSA-fxwm-579q-49qq (nuget) and -https://github.com/advisories/GHSA-wh77-3x4m-4q9g (npm). These two instances -would be described by two separate entries in this vulnerability format as well. - -### summary, details fields - -The `summary` field gives a one-line, English textual summary of the -vulnerability. It is recommended that this field be kept short, on the order of -no more than 120 characters. - -The `details` field gives additional English textual details about the -vulnerability. The field is plain text. Newline characters must be considered -line breaks when displaying the text, but the display need not use a fixed-width -font, and the text should not assume one. - -The `summary` field is plain text. - -The `details` field is CommonMark markdown (a subset of GitHub-Flavored -Markdown). Display code may at its discretion sanitize the input further, such -as stripping raw HTML and links that do not start with http:// or https://. -Databases are encouraged not to include those in the first place. (The goal is -to balance flexibility of presentation with not exposing vulnerability database -display sites to unnecessary vulnerabilities.) - -### affects fields - -The `affects` field is a JSON object that describes the affected versions, -meaning those containing the vulnerability. Within the `affects` object, the -`versions` field can enumerate a specific set of affected versions, and the -`ranges` field can list ranges of affected versions, under a given defined -ordering. A version is considered affected if it lies within any one of the -ranges or is listed in the versions list. +#### affected[].versions -The `versions` list should - with one exception - always be present, to allow -software to answer the question "is this specific version affected?" without -having to contain code specific to every different ecosystem. The one exception -is if the affected versions are valid SemVer 2.0 versions which can be -accurately summarized by one or more non-overlapping SemVer ranges. In that -case, the SemVer ranges can be listed instead, in entries in the `ranges` field -with type `SEMVER` (see below). In this case, the SemVer ranges act as a kind of -compact form of a larger `versions` list. Ecosystems that do not use SemVer -identifiers or that order versions differently from SemVer must include the -enumerated `versions` list, although they can also add ranges of type -`ECOSYSTEM` for additional context. - -In short, the `affects` field must contain either a non-empty `versions` list or -at least one range in the `ranges` list of type `SEMVER`. - -#### affects.versions - -The `affects` object's `versions` field is a JSON array of strings. Each string +The `affected` object's `versions` field is a JSON array of strings. Each string is a single affected version in whatever version syntax is used by the given -package ecosystem. +package ecosystem. -#### affects.ranges +#### affected[].ranges -The `affects` object's `ranges` field is a JSON array of objects, each +The `affected` object's `ranges` field is a JSON array of objects, each describing a single range. The range object defines the fields `type`, `introduced`, `fixed`, and additional type-specific fields as needed. @@ -320,36 +317,27 @@ cannot be answered without access to a copy of the underlying Git repository. Again, it is important to note that to allow portable (non-ecosystem-specific) processors to answer "is this version affected?", either `SEMVER` ranges or an -explicit `affects.versions` list must be given. The `ECOSYSTEM` and `GIT` ranges +explicit `versions` list must be given. The `ECOSYSTEM` and `GIT` ranges are only for adding additional context. -### references field +#### affected[].platforms field -The `references` field contains a list of JSON objects describing references. -Each object has a string field `type` specifying the type of reference, and a -string field `url`. The `url` is the fully-qualified URL (including the scheme, -typically "https://") linking to additional information, advisories, issue -tracker entries, and so on about the vulnerability itself. The `type` specifies -what kind of reference the URL is. +The `affected` object's `platforms` field is a JSON array of strings. Each +string describes a platform that is affected. The values of these strings are +ecosystem-dependent. -The known reference `type` values are: +#### affected[].routines field -- `ADVISORY`: A published security advisory for the vulnerability. -- `ARTICLE`: An article or blog post describing the vulnerability. -- `REPORT`: A report, typically on a bug or issue tracker, of the vulnerability. -- `FIX`: A source code browser link to the fix (e.g., a GitHub commit) Note that - the `fix` type is meant for viewing by people using web browsers. Programs - interested in analyzing the exact commit range would do better to use the - `GIT`-typed `affects.ranges` entries (described above). -- `PACKAGE`: A web page for the affected package itself. -- `WEB`: A web page of some unspecified kind. +The `affected` object's `routines` field is a JSON array of strings. Each string +describes affected source code functions, methods, subroutines, or procedures +that are affected. The values of these strings are ecosystem-dependent. -### ecosystem_specific field +#### affected[].ecosystem_specific field -The `ecosystem_specific` field is a JSON object holding additional information -about the vulnerability as defined by the ecosystem for which the record -applies. The meaning of the values within the object is entirely defined by the -ecosystem and beyond the scope of this document. +The `affected` object's `ecosystem_specific` field is a JSON object holding +additional information about the vulnerability as defined by the ecosystem for +which the record applies. The meaning of the values within the object is +entirely defined by the ecosystem and beyond the scope of this document. For example, the Go ecosystem includes here information about the affected functions and which modules the packages were found in, along with severity in @@ -358,27 +346,52 @@ the Go project-specific severity scale. Note that this is a single field with key "ecosystem_specific", which itself contains a JSON object with unspecified fields. -### database_specific field +#### affected[].database_specific field -The `database_specific` field is a JSON object holding additional information -about the vulnerability as defined by the database from which the record was -obtained. The meaning of the values within the object is entirely defined by the -database and beyond the scope of this document. +The `affected` object's `database_specific` field is a JSON object holding +additional information about the vulnerability as defined by the database from +which the record was obtained. The meaning of the values within the object is +entirely defined by the database and beyond the scope of this document. In general, the canonical database for a particular ecosystem should record its information in `ecosystem_specific`, allowing other aggregator databases to put their own summaries in `database_specific`. -For example, databases that add additional information such as computed CVSS scores for ecosystems that do not provide them could add that information here. +For example, databases that add additional information such as computed CVSS +scores for ecosystems that do not provide them could add that information here. + +Note that this is a single field with key "database_specific", which itself +contains a JSON object with unspecified fields. + -Note that this is a single field with key "database_specific", which itself contains a JSON object with unspecified fields. +### references field + +The `references` field contains a list of JSON objects describing references. +Each object has a string field `type` specifying the type of reference, and a +string field `url`. The `url` is the fully-qualified URL (including the scheme, +typically "https://") linking to additional information, advisories, issue +tracker entries, and so on about the vulnerability itself. The `type` specifies +what kind of reference the URL is. + +The known reference `type` values are: + +- `ADVISORY`: A published security advisory for the vulnerability. +- `ARTICLE`: An article or blog post describing the vulnerability. +- `REPORT`: A report, typically on a bug or issue tracker, of the vulnerability. +- `FIX`: A source code browser link to the fix (e.g., a GitHub commit) Note that + the `fix` type is meant for viewing by people using web browsers. Programs + interested in analyzing the exact commit range would do better to use the + `GIT`-typed `affected[].ranges` entries (described above). +- `PACKAGE`: A web page for the affected package itself. +- `WEB`: A web page of some unspecified kind. ## Examples ### Go vulnerability -The Go vulnerability database and ecosystem define that the `ecosystem_specific` field is a JSON object with additional fields including `functions`, -a list of specific functions that must be called in order to trigger the vulnerability, and `module`, the Go module in which the package appears. +The Go vulnerability database and ecosystem define that the `ecosystem_specific` +field is a JSON object with additional fields including `module`, the Go module +in which the package appears. Here is a complete entry for a recent Go vulnerability: @@ -388,34 +401,34 @@ Here is a complete entry for a recent Go vulnerability: "published": "2021-01-21T19:15:00Z", "modified": "2021-03-10T23:20:53Z", "aliases": ["CVE-2021-3114"], - "package": { - "ecosystem": "Go", - "name": "crypto/elliptic" - }, "summary": "incorrect P-224 curve operations", "details": "The P224() Curve implementation can in rare circumstances generate incorrect outputs, including returning invalid points from ScalarMult.\n\nThe crypto/x509 and golang.org/x/crypto/ocsp (but not crypto/tls) packages support P-224 ECDSA keys, but they are not supported by publicly trusted certificate authorities. No other standard library or golang.org/x/crypto package supports or uses the P-224 curve.\n\nThe incorrect output was found by the elliptic-curve-differential-fuzzer project running on OSS-Fuzz and reported by Philippe Antoine (Catena cyber).", "references": [ {"type": "REPORT", "url": "https://golang.org/issue/43786"}, {"type": "WEB", "url": "https://github.com/catenacyber/elliptic-curve-differential-fuzzer"}, ], - "affects": { + "affected": [ { + "package": { + "ecosystem": "Go", + "name": "crypto/elliptic" + }, "ranges": [ {"type": "SEMVER", "introduced": "1.0.0", "fixed": "1.14.14"}, {"type": "SEMVER", "introduced": "1.15.0", "fixed": "1.15.17"} ] - }, - "ecosystem_specific": { - "functions": ["P224"], - "module": "std", - "severity": "HIGH" - } + "routines": ["P224"], + "ecosystem_specific": { + "module": "std", + "severity": "HIGH" + } + } ] } ``` ### Go tool vulnerability -The shared format can also be used to describe vulnerabilities in commands and applications. -Here is an entry for a recent Go tool vulnerability: +The shared format can also be used to describe vulnerabilities in commands and +applications. Here is an entry for a recent Go tool vulnerability: ```json { @@ -423,24 +436,24 @@ Here is an entry for a recent Go tool vulnerability: "published": "2021-01-21T19:15:00Z", "modified": "2021-03-10T23:20:53Z", "aliases": ["CVE-2021-3115"], - "package": { - "ecosystem": "Go", - "name": "cmd/go" - }, "summary": "packages using cgo can cause arbitrary code execution at build time", "details": "The go command may execute arbitrary code at build time when cgo is in use on Windows. This may occur when running "go get", or any other command that builds code. Only users who build untrusted code (and don’t execute it) are affected.\n\nIn addition to Windows users, this can also affect Unix users who have "." listed explicitly in their PATH and are running "go get" or build commands outside of a module or with module mode disabled.\n\nThanks to RyotaK (https://twitter.com/ryotkak) for reporting this issue.", "references": [ {"type": "REPORT", "url": "https://golang.org/issue/43783"} ], - "affects": { + "affected": [ { + "package": { + "ecosystem": "Go", + "name": "cmd/go" + }, "ranges": [ {"type": "SEMVER", "introduced": "1.0.0", "fixed": "1.14.14"}, {"type": "SEMVER", "introduced": "1.15.0", "fixed": "1.15.17"} - ] - }, - "ecosystem_specific": { - "severity": "HIGH" - } + ], + "ecosystem_specific": { + "severity": "HIGH" + } + } ] } ``` @@ -455,10 +468,6 @@ Neither GitHub nor NPM uses this format currently, but here is how a recent NPM "modified": "2021-03-10T23:40:39Z", "aliases": ["NPM-1648", "CVE-2020-28498", "SNYK-JS-ELLIPTIC-1064899"], "related": ["NPM-1649", "SNYK-JAVA-ORGWEBJARSNPM-1069836"], - "package": { - "ecosystem": "npm", - "name": "elliptic" - }, "summary": "Use of a Broken or Risky Cryptographic Algorithm", "details": "elliptic is a Fast elliptic-curve cryptography in a plain javascript implementation.\n\nAffected versions of this package are vulnerable to Cryptographic Issues via the secp256k1 implementation in elliptic/ec/key.js. There is no check to confirm that the public key point passed into the derive function actually exists on the secp256k1 curve. This results in the potential for the private key used in this implementation to be revealed after a number of ECDH operations are performed.\n\nRemediation: Upgrade elliptic to version 6.5.4 or higher.\n", "references": [ @@ -469,20 +478,24 @@ Neither GitHub nor NPM uses this format currently, but here is how a recent NPM {"type": "ADVISORY", "url": "https://snyk.io/vuln/SNYK-JS-ELLIPTIC-1064899"}, {"type": "PACKAGE", "url": "https://www.npmjs.com/package/elliptic"} ], - "affects": { + "affected": [ { + "package": { + "ecosystem": "npm", + "name": "elliptic" + }, "ranges": [ {"type": "SEMVER", "fixed": "6.5.4"}, {"type": "SEMVER", "introduced": "1.15.0", "fixed": "1.15.17"} - ] - }, - "database_specific": { - "CWE": "CWE-327", - "CVSS": { - "Score": "6.8", - "Severity": "Medium", - "Code": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:N/A:N" + ], + "database_specific": { + "CWE": "CWE-327", + "CVSS": { + "Score": "6.8", + "Severity": "Medium", + "Code": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:N/A:N" + } } - } + } ] } ``` @@ -495,16 +508,16 @@ OSV uses this format already for its vulnerabilities. Here is the encoding of on "id": "OSV-2020-584", "published": "TODO 2021-01-21T19:15:00Z", "modified": "TODO 2021-03-10T23:20:53Z", - "package": { - "ecosystem": "OSS-Fuzz", - "name": "icu" - }, "summary": "Heap-buffer-overflow in collator_compare_fuzzer.cpp", "details": "OSS-Fuzz report: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=15499\nCrash type: Heap-buffer-overflow WRITE 3\nCrash state:\ncollator_compare_fuzzer.cpp\n", "references": [ {"type": "REPORT", "url": "https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=15499"}, ], - "affects": { + "affected": [ { + "package": { + "ecosystem": "OSS-Fuzz", + "name": "icu" + }, "ranges": [ { "type": "GIT", @@ -513,7 +526,7 @@ OSV uses this format already for its vulnerabilities. Here is the encoding of on "repo": "https://github.com/unicode-org/icu.git" } ] - } + } ] } ``` @@ -528,27 +541,27 @@ format. Here’s an example entry: "published": "2019-11-16T00:00:00Z", "modified": "2021-01-04T19:02:00Z", "aliases": ["CVE-2020-25574", "CVE-2019-25008"], - "package": { - "ecosystem": "crates.io", - "name": "http" - }, "summary": "Integer Overflow in HeaderMap::reserve() can cause Denial of Service", "details": "HeaderMap::reserve() used usize::next_power_of_two() to calculate\nthe increased capacity. However, next_power_of_two() silently overflows\nto 0 if given a sufficently large number in release mode.\n\nIf the map was not empty when the overflow happens, the library will invoke self.grow(0)\nand start infinite probing. This allows an attacker who controls\nthe argument to reserve() to cause a potential denial of service (DoS).\n\nThe flaw was corrected in 0.1.20 release of http crate.\n", "references": [ {"type": "REPORT", "url": "https://github.com/hyperium/http/issues/352"}, {"type": "ADVISORY", "url": "https://rustsec.org/advisories/RUSTSEC-2019-0033.html"} ], - "affects": { + "affected": [ { + "package": { + "ecosystem": "crates.io", + "name": "http" + }, "ranges": [ {"type": "SEMVER", "fixed": "0.1.20"}, - ] - }, - "ecosystem_specific": { - "functions": ["http::header::HeaderMap::reserve"], - "keywords": ["http", "integer-overflow", "DoS"], - "categories": ["denial-of-service"], - "severity": "HIGH" - } + ], + "routines": ["http::header::HeaderMap::reserve"], + "ecosystem_specific": { + "keywords": ["http", "integer-overflow", "DoS"], + "categories": ["denial-of-service"], + "severity": "HIGH" + } + } ] } ``` @@ -564,16 +577,16 @@ potential encoding of a vulnerability entry. "published": "2021-04-01T20:15:00Z", "modified": "2021-04-07T15:14:00Z", "aliases": ["CVE-2021-29421"], - "package": { - "ecosystem": "PyPI", - "name": "pikepdf" - }, "summary": "XXE in pikepdf", "details": "models/metadata.py in the pikepdf package 2.8.0 through 2.9.2 for Python allows XXE when parsing XMP metadata entries.", "references": [ {"type": "FIX", "url": "https://github.com/pikepdf/pikepdf/commit/3f38f73218e5e782fe411ccbb3b44a793c0b343a"} ], - "affects": { + "affected": [ { + "package": { + "ecosystem": "PyPI", + "name": "pikepdf" + }, "ranges": [ { "type": "GIT", @@ -586,13 +599,13 @@ potential encoding of a vulnerability entry. "fixed": "2.10.0" } ], - "versions": [ - "2.8.0", "2.8.0.post1", "2.8.0.post2", "2.9.0", "2.9.1", "2.9.2" - ], - }, - "ecosystem_specific": { - "severity": "HIGH" - } + "versions": [ + "2.8.0", "2.8.0.post1", "2.8.0.post2", "2.9.0", "2.9.1", "2.9.2" + ], + "ecosystem_specific": { + "severity": "HIGH" + } + } ] } ``` @@ -604,13 +617,13 @@ Ruby does not use this format currently, but here is a potential translation of "id": "CVE-2019-3881", "published": "2018-04-23T00:00:00Z", "modified": "2021-05-10T00:00:00Z", - "package": { - "ecosystem": "RubyGems", - "name": "bundler" - }, "summary": "Insecure path handling in Bundler", "details": "Bundler prior to 2.1.0 uses a predictable path in /tmp/, created with insecure permissions as a storage location for gems, if locations under the user's home directory are not available. If Bundler is used in a scenario where the user does not have a writable home directory, an attacker could place malicious code in this directory that would be later loaded and executed.", - "affects": { + "affected": [ { + "package": { + "ecosystem": "RubyGems", + "name": "bundler" + }, "ranges": [ {"type": "ECOSYSTEM", "introduced": "1.14.0", "fixed": "2.1.0"} ], @@ -624,7 +637,7 @@ Ruby does not use this format currently, but here is a potential translation of "1.17.3", "2.0.0.pre.1", "2.0.0.pre.2", "2.0.0.pre.3", "2.0.0", "2.0.1", "2.0.2", "2.1.0.pre.1", "2.1.0.pre.2", "2.1.0.pre.3" ] - }, + } ], "references": [ {"type": "ADVISORY", "url": "https://github.com/advisories/GHSA-g98m-96g9-wfjq"} ] @@ -643,6 +656,10 @@ Ruby does not use this format currently, but here is a potential translation of - 2021-06-08 Added "purl" to the "package" field and some minor clarifications. - 2021-06-30 Fixed an incorrect/typoed specification for "affects" from an array of objects to an object. +- 2021-08-05 Support multiple packages per entry by moving, `packages`, + `ecosystem_specific` and `database_specific` into a `affected`. The `affected` + field is intentionally named differently to the previous `affects` field to + make migration easier. ## Status - 2021-04-07 @@ -762,3 +779,24 @@ Based on that, added some new reference types. My plan is to rewrite the italicized paragraph at the top of the doc on Monday and then share the link publicly to gather more feedback from groups that have not yet seen it. + +## Status - 2021-08-05 + +The biggest change to the schema is our decision to support multiple packages +and ecosystems per entry. This is a reversal of our decision back in April (see +"Status - 2021-04-23" for our rationale). + +This is primarily in the interests of supporting better interoperability with +other vulnerability schemas, such as the [CVE JSON +schema](https://github.com/CVEProject/cve-schema), +where multiple packages are supported in a single entry. We've +also been suggesting changes to the CVE schema as well for better +alignment. +([1](https://github.com/CVEProject/cve-schema/issues/86), + [2](https://github.com/CVEProject/cve-schema/issues/87), + [3](https://github.com/CVEProject/cve-schema/issues/88), + [4](https://github.com/CVEProject/cve-schema/issues/89)), + +This is a breaking change, but we hope to make migration easier by renaming the +"affects" field to "affected" to allow existing consumers and producers of this +data to more easily handle old and new versions of entries. From fc88d28b70f42ca3034d973b130c169fa0400a7b Mon Sep 17 00:00:00 2001 From: Oliver Chang Date: Thu, 5 Aug 2021 16:47:35 +1000 Subject: [PATCH 02/22] various small typos --- schema.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/schema.md b/schema.md index 9ab0b5e3..bce886f6 100644 --- a/schema.md +++ b/schema.md @@ -363,7 +363,6 @@ scores for ecosystems that do not provide them could add that information here. Note that this is a single field with key "database_specific", which itself contains a JSON object with unspecified fields. - ### references field The `references` field contains a list of JSON objects describing references. @@ -415,7 +414,7 @@ Here is a complete entry for a recent Go vulnerability: "ranges": [ {"type": "SEMVER", "introduced": "1.0.0", "fixed": "1.14.14"}, {"type": "SEMVER", "introduced": "1.15.0", "fixed": "1.15.17"} - ] + ], "routines": ["P224"], "ecosystem_specific": { "module": "std", @@ -656,10 +655,10 @@ Ruby does not use this format currently, but here is a potential translation of - 2021-06-08 Added "purl" to the "package" field and some minor clarifications. - 2021-06-30 Fixed an incorrect/typoed specification for "affects" from an array of objects to an object. -- 2021-08-05 Support multiple packages per entry by moving, `packages`, - `ecosystem_specific` and `database_specific` into a `affected`. The `affected` - field is intentionally named differently to the previous `affects` field to - make migration easier. +- 2021-08-05 Support multiple packages per entry by moving `packages`, + `ecosystem_specific` and `database_specific` into `affected`. Added `routines` + and `platforms` to `affected` as well. The `affected` field is intentionally + named differently to the previous `affects` field to make migration easier. ## Status - 2021-04-07 @@ -791,11 +790,11 @@ other vulnerability schemas, such as the [CVE JSON schema](https://github.com/CVEProject/cve-schema), where multiple packages are supported in a single entry. We've also been suggesting changes to the CVE schema as well for better -alignment. +alignment ([1](https://github.com/CVEProject/cve-schema/issues/86), [2](https://github.com/CVEProject/cve-schema/issues/87), [3](https://github.com/CVEProject/cve-schema/issues/88), - [4](https://github.com/CVEProject/cve-schema/issues/89)), + [4](https://github.com/CVEProject/cve-schema/issues/89)). This is a breaking change, but we hope to make migration easier by renaming the "affects" field to "affected" to allow existing consumers and producers of this From d91ae7063c838166e649c17631ef4f0e72ec7a54 Mon Sep 17 00:00:00 2001 From: Oliver Chang Date: Thu, 5 Aug 2021 16:53:22 +1000 Subject: [PATCH 03/22] consistent tense --- schema.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/schema.md b/schema.md index bce886f6..28beb81c 100644 --- a/schema.md +++ b/schema.md @@ -329,8 +329,8 @@ ecosystem-dependent. #### affected[].routines field The `affected` object's `routines` field is a JSON array of strings. Each string -describes affected source code functions, methods, subroutines, or procedures -that are affected. The values of these strings are ecosystem-dependent. +describes a source code function, method or subroutine that is affected. The +values of these strings are ecosystem-dependent. #### affected[].ecosystem_specific field From 9faf5461c9aeca2eec0393da91a47e284388fa8d Mon Sep 17 00:00:00 2001 From: Oliver Chang Date: Thu, 5 Aug 2021 16:56:24 +1000 Subject: [PATCH 04/22] add clarification --- schema.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/schema.md b/schema.md index 28beb81c..22e7efa3 100644 --- a/schema.md +++ b/schema.md @@ -186,7 +186,8 @@ The `affected` field is a JSON array containing objects that describes the affected packages versions, meaning those that contain the vulnerability. Within each object in the `affected` array, the `package` field identifies the -package containing the vulnerability. +package containing the vulnerability. There should be exactly one entry in the +`affected` array per `package`. The `versions` field can enumerate a specific set of affected versions, and the `ranges` field can list ranges of affected versions, under a given defined @@ -324,13 +325,13 @@ are only for adding additional context. The `affected` object's `platforms` field is a JSON array of strings. Each string describes a platform that is affected. The values of these strings are -ecosystem-dependent. +defined by the ecosystem. #### affected[].routines field The `affected` object's `routines` field is a JSON array of strings. Each string describes a source code function, method or subroutine that is affected. The -values of these strings are ecosystem-dependent. +values of these strings are defined by the ecosystem. #### affected[].ecosystem_specific field From af617776282a9b9bed0a9af36a77ae78547585ca Mon Sep 17 00:00:00 2001 From: Oliver Chang Date: Thu, 5 Aug 2021 16:59:12 +1000 Subject: [PATCH 05/22] nit --- schema.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/schema.md b/schema.md index 22e7efa3..a63a6f1b 100644 --- a/schema.md +++ b/schema.md @@ -187,7 +187,7 @@ affected packages versions, meaning those that contain the vulnerability. Within each object in the `affected` array, the `package` field identifies the package containing the vulnerability. There should be exactly one entry in the -`affected` array per `package`. +`affected` array per affected `package`. The `versions` field can enumerate a specific set of affected versions, and the `ranges` field can list ranges of affected versions, under a given defined @@ -790,8 +790,7 @@ This is primarily in the interests of supporting better interoperability with other vulnerability schemas, such as the [CVE JSON schema](https://github.com/CVEProject/cve-schema), where multiple packages are supported in a single entry. We've -also been suggesting changes to the CVE schema as well for better -alignment +also been suggesting changes to the CVE schema for better alignment ([1](https://github.com/CVEProject/cve-schema/issues/86), [2](https://github.com/CVEProject/cve-schema/issues/87), [3](https://github.com/CVEProject/cve-schema/issues/88), From 03cde249b82f533a48b453cdfc8739e7e098ec94 Mon Sep 17 00:00:00 2001 From: Oliver Chang Date: Fri, 6 Aug 2021 11:59:10 +1000 Subject: [PATCH 06/22] changes --- schema.md | 32 +++++++++++--------------------- 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/schema.md b/schema.md index a63a6f1b..01e29bc8 100644 --- a/schema.md +++ b/schema.md @@ -71,8 +71,6 @@ contain UTF-8 text. "fixed": string } ], "versions": [ string ], - "platforms": [ string ], - "routines": [ string ], "ecosystem_specific": { see description }, "database_specific": { see description }, } ], @@ -186,8 +184,12 @@ The `affected` field is a JSON array containing objects that describes the affected packages versions, meaning those that contain the vulnerability. Within each object in the `affected` array, the `package` field identifies the -package containing the vulnerability. There should be exactly one entry in the -`affected` array per affected `package`. +package containing the vulnerability. In most cases, there should be exactly one +entry in the `affected` array per affected `package` to describe all affected +versions. In rare cases, for example if the `ecosystem_specific` encodes +platform information that doesn't apply equally to all listed versions and +ranges, a separate entry with the same `package` in the `affected` array may be +used. The `versions` field can enumerate a specific set of affected versions, and the `ranges` field can list ranges of affected versions, under a given defined @@ -321,18 +323,6 @@ processors to answer "is this version affected?", either `SEMVER` ranges or an explicit `versions` list must be given. The `ECOSYSTEM` and `GIT` ranges are only for adding additional context. -#### affected[].platforms field - -The `affected` object's `platforms` field is a JSON array of strings. Each -string describes a platform that is affected. The values of these strings are -defined by the ecosystem. - -#### affected[].routines field - -The `affected` object's `routines` field is a JSON array of strings. Each string -describes a source code function, method or subroutine that is affected. The -values of these strings are defined by the ecosystem. - #### affected[].ecosystem_specific field The `affected` object's `ecosystem_specific` field is a JSON object holding @@ -416,8 +406,8 @@ Here is a complete entry for a recent Go vulnerability: {"type": "SEMVER", "introduced": "1.0.0", "fixed": "1.14.14"}, {"type": "SEMVER", "introduced": "1.15.0", "fixed": "1.15.17"} ], - "routines": ["P224"], "ecosystem_specific": { + "functions": ["P224"], "module": "std", "severity": "HIGH" } @@ -555,8 +545,8 @@ format. Here’s an example entry: "ranges": [ {"type": "SEMVER", "fixed": "0.1.20"}, ], - "routines": ["http::header::HeaderMap::reserve"], "ecosystem_specific": { + "functions": ["http::header::HeaderMap::reserve"], "keywords": ["http", "integer-overflow", "DoS"], "categories": ["denial-of-service"], "severity": "HIGH" @@ -657,9 +647,9 @@ Ruby does not use this format currently, but here is a potential translation of - 2021-06-30 Fixed an incorrect/typoed specification for "affects" from an array of objects to an object. - 2021-08-05 Support multiple packages per entry by moving `packages`, - `ecosystem_specific` and `database_specific` into `affected`. Added `routines` - and `platforms` to `affected` as well. The `affected` field is intentionally - named differently to the previous `affects` field to make migration easier. + `ecosystem_specific` and `database_specific` into `affected`. The `affected` + field is intentionally named differently to the previous `affects` field to + make migration easier. ## Status - 2021-04-07 From 8b8793bb2e9e4118c1fa0b867df6ba79b559bfb6 Mon Sep 17 00:00:00 2001 From: Oliver Chang Date: Fri, 6 Aug 2021 14:11:02 +1000 Subject: [PATCH 07/22] address comments --- schema.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/schema.md b/schema.md index 01e29bc8..e9650630 100644 --- a/schema.md +++ b/schema.md @@ -181,7 +181,7 @@ display sites to unnecessary vulnerabilities.) ### affected fields The `affected` field is a JSON array containing objects that describes the -affected packages versions, meaning those that contain the vulnerability. +affected package versions, meaning those that contain the vulnerability. Within each object in the `affected` array, the `package` field identifies the package containing the vulnerability. In most cases, there should be exactly one @@ -189,7 +189,7 @@ entry in the `affected` array per affected `package` to describe all affected versions. In rare cases, for example if the `ecosystem_specific` encodes platform information that doesn't apply equally to all listed versions and ranges, a separate entry with the same `package` in the `affected` array may be -used. +needed. The `versions` field can enumerate a specific set of affected versions, and the `ranges` field can list ranges of affected versions, under a given defined @@ -789,3 +789,6 @@ also been suggesting changes to the CVE schema for better alignment This is a breaking change, but we hope to make migration easier by renaming the "affects" field to "affected" to allow existing consumers and producers of this data to more easily handle old and new versions of entries. + +We are still gathering experience about this new arrangement, and it may change +again in the near future. From 67693a7111bd4813a5a1d79eb63a4ec3d87ed831 Mon Sep 17 00:00:00 2001 From: Oliver Chang Date: Tue, 10 Aug 2021 09:23:48 +1000 Subject: [PATCH 08/22] move repo --- schema.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/schema.md b/schema.md index e9650630..f4b5b6f2 100644 --- a/schema.md +++ b/schema.md @@ -64,9 +64,9 @@ contain UTF-8 text. "name": string, "purl": string, }, + "repo": string, "ranges": [ { "type": string, - "repo": string, "introduced": string, "fixed": string } ], @@ -258,6 +258,12 @@ It is permitted for a database name (the DB prefix in the `id` field) and an ecosystem name to be the same, provided they have the same owner who can make decisions about the meaning of the `ecosystem_specific` field (see below). +#### affected[].repo field + +The `affected` object's `repo` field is the URL of the package's code +repository. The value should be in a format that's directly usable as an +argument for the version control system's clone command (e.g. `git clone`). + #### affected[].versions The `affected` object's `versions` field is a JSON array of strings. Each string @@ -307,8 +313,7 @@ ecosystem’s own logic and therefore cannot be used by ecosystem-independent processors. - `GIT`: The versions `introduced` and `fixed` are full-length Git commit hashes. -The additional field `repo` is the URL of the Git repository (as used with `git -clone`). The repository’s commit graph is needed to evaluate whether a given +The repository’s commit graph is needed to evaluate whether a given version is in the range. The relation `u < v` is true when commit `u` is a (perhaps distant) parent of commit `v`. Ranges listed with type `GIT` may need to overlap, if a vulnerability with a single root cause was fixed independently on multiple @@ -504,6 +509,7 @@ OSV uses this format already for its vulnerabilities. Here is the encoding of on {"type": "REPORT", "url": "https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=15499"}, ], "affected": [ { + "repo": "https://github.com/unicode-org/icu.git", "package": { "ecosystem": "OSS-Fuzz", "name": "icu" @@ -513,7 +519,6 @@ OSV uses this format already for its vulnerabilities. Here is the encoding of on "type": "GIT", "introduced": "6e5755a2a833bc64852eae12967d0a54d7adf629", "fixed": "c43455749b914feef56b178b256f29b3016146eb", - "repo": "https://github.com/unicode-org/icu.git" } ] } ] @@ -573,6 +578,7 @@ potential encoding of a vulnerability entry. {"type": "FIX", "url": "https://github.com/pikepdf/pikepdf/commit/3f38f73218e5e782fe411ccbb3b44a793c0b343a"} ], "affected": [ { + "repo": "https://github.com/pikepdf/pikepdf", "package": { "ecosystem": "PyPI", "name": "pikepdf" @@ -580,7 +586,6 @@ potential encoding of a vulnerability entry. "ranges": [ { "type": "GIT", - "repo": "https://github.com/pikepdf/pikepdf", "fixed": "3f38f73218e5e782fe411ccbb3b44a793c0b343a" }, { From a302f9e28f254a4cbe55dea818f36584c3698b89 Mon Sep 17 00:00:00 2001 From: Oliver Chang Date: Tue, 17 Aug 2021 14:19:02 +1000 Subject: [PATCH 09/22] events --- schema.md | 214 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 156 insertions(+), 58 deletions(-) diff --git a/schema.md b/schema.md index f4b5b6f2..8e06941b 100644 --- a/schema.md +++ b/schema.md @@ -64,11 +64,13 @@ contain UTF-8 text. "name": string, "purl": string, }, - "repo": string, "ranges": [ { "type": string, - "introduced": string, - "fixed": string + "repo": string, + "events": [ { + "introduced": string, + "fixed": string + } ] } ], "versions": [ string ], "ecosystem_specific": { see description }, @@ -258,46 +260,64 @@ It is permitted for a database name (the DB prefix in the `id` field) and an ecosystem name to be the same, provided they have the same owner who can make decisions about the meaning of the `ecosystem_specific` field (see below). -#### affected[].repo field - -The `affected` object's `repo` field is the URL of the package's code -repository. The value should be in a format that's directly usable as an -argument for the version control system's clone command (e.g. `git clone`). - -#### affected[].versions +#### affected[].versions field The `affected` object's `versions` field is a JSON array of strings. Each string is a single affected version in whatever version syntax is used by the given package ecosystem. -#### affected[].ranges +#### affected[].ranges[] field -The `affected` object's `ranges` field is a JSON array of objects, each -describing a single range. The range object defines the fields `type`, -`introduced`, `fixed`, and additional type-specific fields as needed. +The `affected` object's `ranges` field is a JSON array of objects describing the +affected ranges of versions. -In the range object, the `type` field is required. It specifies the type of -version range being recorded and defines the interpretation of `introduced`, -`fixed`, and any type-specific fields. +#### affected[].ranges[].events field + +The `ranges` object's `events` field is a JSON array of objects. Each object +describes a single version that either introduces, or fixes a vulnerability (but +**not both**). + +For example, the following expresses that versions in the SemVer ranges `[1.0.0, +1.0.2)` or `[1.1.1, 1.1.5)` are affected. Everything else is unaffected. + +``` +"ranges": [{ + "type: "SEMVER", + "events": [ + { "introduced": "1.0.0" }, + { "fixed": "1.0.2" }, + { "introduced": "1.1.1" }, + { "fixed": "1.1.5" } + ] +}] +``` -The `introduced` and `fixed` fields specify the range of versions containing the -vulnerability. The vulnerability is considered present in version v if: +An algorithm for computing if a version `v` is affected can be done as follows: ``` -(introduced is unset OR introduced < v OR introduced == v) AND -(fixed is unset OR v < fixed). +status = UNAFFECTED +for evt in sorted(ranges.events) + if evt.introduced && v >= evt.introduced + status = AFFECTED + else if evt.fixed && v >= evt.fixed + status = UNAFFECTED + +return status ``` -Here `u == v` is exact version equality and the meaning of the relation `u < v` -depends on the type. +Here the meaning of the relation `u >= v` and `sorted()` depends on the type. + +#### affected[].ranges[].type field + +In the `ranges` field, the `type` field is required. It specifies the type of +version range being recorded and defines the interpretation of the `events` +object's `introduced`, `fixed`, and any type-specific fields. The defined types and their additional fields are: - `SEMVER`: The versions `introduced` and `fixed` are semantic versions as defined by [SemVer 2.0.0](https://semver.org), with no leading "v" prefix. The relation -`u < v` denotes the precedence order defined in [section 11 of SemVer 2.0](https://semver.org/#spec-item-11). -Ranges listed with type `SEMVER` should not overlap: since SEMVER is a strict -linear ordering, it is always possible to simplify to non-overlapping ranges. +`u >= v` denotes the precedence order defined in [section 11 of SemVer 2.0](https://semver.org/#spec-item-11). Specifying one or more `SEMVER` ranges removes the requirement to specify an explicit enumerated `versions` list (see the discussion above). @@ -312,12 +332,11 @@ inclusion queries cannot be answered without reference to the package ecosystem’s own logic and therefore cannot be used by ecosystem-independent processors. -- `GIT`: The versions `introduced` and `fixed` are full-length Git commit hashes. -The repository’s commit graph is needed to evaluate whether a given -version is in the range. The relation `u < v` is true when commit `u` is a (perhaps -distant) parent of commit `v`. Ranges listed with type `GIT` may need to overlap, -if a vulnerability with a single root cause was fixed independently on multiple -branches. +- `GIT`: The versions `introduced` and `fixed` are full-length Git commit + hashes. The repository’s commit graph is needed to evaluate whether a given + version is in the range. The relation `u >= v` is true when commit `u` is + either the exact same commit as `v`, or `v` is a (perhaps distant) parent of + commit `u`. Specifying one or more `GIT` ranges does NOT remove the requirement to specify an explicitly enumerated `versions` list, because `GIT` range inclusion queries @@ -328,6 +347,19 @@ processors to answer "is this version affected?", either `SEMVER` ranges or an explicit `versions` list must be given. The `ECOSYSTEM` and `GIT` ranges are only for adding additional context. +#### affected[].ranges[].repo field + +The `ranges` object's `repo` field is the URL of the package's code +repository. The value should be in a format that's directly usable as an +argument for the version control system's clone command (e.g. `git clone`). + +The `affected` object's `ranges` field is a JSON array of objects, each +describing a single range. The range object defines the fields `type`, +`events`, `repo`. `introduced`, `fixed`, and additional type-specific fields as needed. + +This field is required if `affected[].ranges[].type` is `GIT`. + + #### affected[].ecosystem_specific field The `affected` object's `ecosystem_specific` field is a JSON object holding @@ -408,8 +440,15 @@ Here is a complete entry for a recent Go vulnerability: "name": "crypto/elliptic" }, "ranges": [ - {"type": "SEMVER", "introduced": "1.0.0", "fixed": "1.14.14"}, - {"type": "SEMVER", "introduced": "1.15.0", "fixed": "1.15.17"} + { + "type": "SEMVER", + "events": [ + { "introduced": "1.0.0" }, + { "fixed": "1.14.14" }, + { "introduced": "1.15.0" }, + { "fixed": "1.15.17" } + ] + } ], "ecosystem_specific": { "functions": ["P224"], @@ -442,8 +481,15 @@ applications. Here is an entry for a recent Go tool vulnerability: "name": "cmd/go" }, "ranges": [ - {"type": "SEMVER", "introduced": "1.0.0", "fixed": "1.14.14"}, - {"type": "SEMVER", "introduced": "1.15.0", "fixed": "1.15.17"} + { + "type": "SEMVER", + "events": [ + { "introduced": "1.0.0" }, + { "fixed": "1.14.14" }, + { "introduced": "1.15.10" }, + { "fixed": "1.15.17" } + ], + } ], "ecosystem_specific": { "severity": "HIGH" @@ -479,8 +525,14 @@ Neither GitHub nor NPM uses this format currently, but here is how a recent NPM "name": "elliptic" }, "ranges": [ - {"type": "SEMVER", "fixed": "6.5.4"}, - {"type": "SEMVER", "introduced": "1.15.0", "fixed": "1.15.17"} + { + "type": "SEMVER", + "events": [ + { "introduced": "1.15.0" }, + { "fixed": "1.15.17" }, + { "fixed": "6.5.4" } + ] + } ], "database_specific": { "CWE": "CWE-327", @@ -517,8 +569,10 @@ OSV uses this format already for its vulnerabilities. Here is the encoding of on "ranges": [ { "type": "GIT", - "introduced": "6e5755a2a833bc64852eae12967d0a54d7adf629", - "fixed": "c43455749b914feef56b178b256f29b3016146eb", + "events": [ + { "introduced": "6e5755a2a833bc64852eae12967d0a54d7adf629" }, + { "fixed": "c43455749b914feef56b178b256f29b3016146eb" } + ] } ] } ] @@ -548,7 +602,10 @@ format. Here’s an example entry: "name": "http" }, "ranges": [ - {"type": "SEMVER", "fixed": "0.1.20"}, + { + "type": "SEMVER", + "events": [ {"fixed": "0.1.20"} ] + } ], "ecosystem_specific": { "functions": ["http::header::HeaderMap::reserve"], @@ -578,7 +635,6 @@ potential encoding of a vulnerability entry. {"type": "FIX", "url": "https://github.com/pikepdf/pikepdf/commit/3f38f73218e5e782fe411ccbb3b44a793c0b343a"} ], "affected": [ { - "repo": "https://github.com/pikepdf/pikepdf", "package": { "ecosystem": "PyPI", "name": "pikepdf" @@ -586,12 +642,17 @@ potential encoding of a vulnerability entry. "ranges": [ { "type": "GIT", - "fixed": "3f38f73218e5e782fe411ccbb3b44a793c0b343a" + "repo": "https://github.com/pikepdf/pikepdf", + "events": [ + { "fixed": "3f38f73218e5e782fe411ccbb3b44a793c0b343a" } + ], }, { "type": "ECOSYSTEM", - "introduced": "2.8.0", - "fixed": "2.10.0" + "events": [ + { "introduced": "2.8.0" }, + { "fixed": "2.10.0" } + ], } ], "versions": [ @@ -619,9 +680,13 @@ Ruby does not use this format currently, but here is a potential translation of "ecosystem": "RubyGems", "name": "bundler" }, - "ranges": [ - {"type": "ECOSYSTEM", "introduced": "1.14.0", "fixed": "2.1.0"} - ], + "ranges": [ { + "type": "ECOSYSTEM", + "events": [ + { "introduced": "1.14.0" }, + { "fixed": "2.1.0" }, + ] + } ], "versions": [ "1.14.0", "1.14.1", "1.14.2", "1.14.3", "1.14.4", "1.14.5", "1.14.6", "1.15.0.pre.1", "1.15.0.pre.2", "1.15.0.pre.3", @@ -778,22 +843,55 @@ not yet seen it. ## Status - 2021-08-05 The biggest change to the schema is our decision to support multiple packages -and ecosystems per entry. This is a reversal of our decision back in April (see +and ecosystems per entry and the way we specify version ranges. + +Supporting multiple packages is a reversal of our decision back in April (see "Status - 2021-04-23" for our rationale). -This is primarily in the interests of supporting better interoperability with -other vulnerability schemas, such as the [CVE JSON -schema](https://github.com/CVEProject/cve-schema), -where multiple packages are supported in a single entry. We've -also been suggesting changes to the CVE schema for better alignment +These changes are primarily in the interests of +supporting better interoperability with other vulnerability schemas, such as the +[CVE JSON schema](https://github.com/CVEProject/cve-schema), where multiple +packages are supported in a single entry. We've also been suggesting other +changes to the CVE schema for better alignment ([1](https://github.com/CVEProject/cve-schema/issues/86), [2](https://github.com/CVEProject/cve-schema/issues/87), [3](https://github.com/CVEProject/cve-schema/issues/88), [4](https://github.com/CVEProject/cve-schema/issues/89)). -This is a breaking change, but we hope to make migration easier by renaming the +The other major change is the way we specify ranges. Instead of specifying half +open ranges as [introduced, fixed), ranges are encoded with with "events" in a +"timeline" of sorts: + +Instead of + +``` +"ranges": [{ + "type: "GIT", + "introduced": "058504edd02667eef8fac9be27ab3ea74332e9b4", + "fixed": "3533e50cbee8ff086bfa04176ac42a01ee3db37d" +}, { + "type": "GIT", + "introduced": "058504edd02667eef8fac9be27ab3ea74332e9b4", + "fixed": "c5157b3e775dac31d51b11f993a06a84dc11fc8c" } +}] +``` + +We now have: + +``` +"ranges": [{ + "type: "SEMVER", + "events": [ + { "introduced": "058504edd02667eef8fac9be27ab3ea74332e9b4" }, + { "fixed": "3533e50cbee8ff086bfa04176ac42a01ee3db37d" }, + { "fixed": "c5157b3e775dac31d51b11f993a06a84dc11fc8c" } + ] +}] +``` + +This avoids repetition with the previous approach and better fits non-linear +versioning schemes like git ranges. + +These are breaking changes, but we hope to make migration easier by renaming the "affects" field to "affected" to allow existing consumers and producers of this data to more easily handle old and new versions of entries. - -We are still gathering experience about this new arrangement, and it may change -again in the near future. From 45dca318e4e062fffd4d565336c7de01bfd49cd7 Mon Sep 17 00:00:00 2001 From: Oliver Chang Date: Tue, 17 Aug 2021 14:28:06 +1000 Subject: [PATCH 10/22] update date --- schema.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schema.md b/schema.md index 8e06941b..5b9df586 100644 --- a/schema.md +++ b/schema.md @@ -1,6 +1,6 @@ # Open Source Vulnerability format -**Version 0.8 (August 5, 2021)** +**Version 0.8 (August 17, 2021)** Original authors: - Oliver Chang (ochang@google.com) From 3c35d8e77e1c0b43fafc23190b51665460efc13f Mon Sep 17 00:00:00 2001 From: Oliver Chang Date: Tue, 17 Aug 2021 14:44:13 +1000 Subject: [PATCH 11/22] clarify changelog --- schema.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/schema.md b/schema.md index 5b9df586..2a218e97 100644 --- a/schema.md +++ b/schema.md @@ -716,10 +716,11 @@ Ruby does not use this format currently, but here is a potential translation of - 2021-06-08 Added "purl" to the "package" field and some minor clarifications. - 2021-06-30 Fixed an incorrect/typoed specification for "affects" from an array of objects to an object. -- 2021-08-05 Support multiple packages per entry by moving `packages`, +- 2021-08-17 Support multiple packages per entry by moving `packages`, `ecosystem_specific` and `database_specific` into `affected`. The `affected` field is intentionally named differently to the previous `affects` field to - make migration easier. + make migration easier. Also use "events" containing single versions to + represent affected version ranges instead. ## Status - 2021-04-07 From 9bff9d559c0aea33904d0e970c49180a42ffe37f Mon Sep 17 00:00:00 2001 From: Oliver Chang Date: Tue, 17 Aug 2021 17:58:36 +1000 Subject: [PATCH 12/22] tentative earlier_affected field. --- schema.md | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/schema.md b/schema.md index 2a218e97..459d3073 100644 --- a/schema.md +++ b/schema.md @@ -67,6 +67,7 @@ contain UTF-8 text. "ranges": [ { "type": string, "repo": string, + "earlier_affected": bool, "events": [ { "introduced": string, "fixed": string @@ -271,6 +272,13 @@ package ecosystem. The `affected` object's `ranges` field is a JSON array of objects describing the affected ranges of versions. +#### affected[].ranges[].earlier_affected field + +The `ranges` object's `earlier_affected` field is a boolean value. If this is +`false` (the default), this means that any versions before the listed `events` +versions should be considered unaffected. Otherwise, these versions should be +considered affected. + #### affected[].ranges[].events field The `ranges` object's `events` field is a JSON array of objects. Each object @@ -295,14 +303,14 @@ For example, the following expresses that versions in the SemVer ranges `[1.0.0, An algorithm for computing if a version `v` is affected can be done as follows: ``` -status = UNAFFECTED +affected = ranges.earlier_affected for evt in sorted(ranges.events) if evt.introduced && v >= evt.introduced - status = AFFECTED + affected = true else if evt.fixed && v >= evt.fixed - status = UNAFFECTED + affected = false -return status +return affected ``` Here the meaning of the relation `u >= v` and `sorted()` depends on the type. @@ -846,9 +854,6 @@ not yet seen it. The biggest change to the schema is our decision to support multiple packages and ecosystems per entry and the way we specify version ranges. -Supporting multiple packages is a reversal of our decision back in April (see -"Status - 2021-04-23" for our rationale). - These changes are primarily in the interests of supporting better interoperability with other vulnerability schemas, such as the [CVE JSON schema](https://github.com/CVEProject/cve-schema), where multiple @@ -859,6 +864,9 @@ changes to the CVE schema for better alignment [3](https://github.com/CVEProject/cve-schema/issues/88), [4](https://github.com/CVEProject/cve-schema/issues/89)). +Supporting multiple packages is a reversal of our decision back in April (see +"Status - 2021-04-23" for our rationale at the time). + The other major change is the way we specify ranges. Instead of specifying half open ranges as [introduced, fixed), ranges are encoded with with "events" in a "timeline" of sorts: @@ -874,6 +882,14 @@ Instead of "type": "GIT", "introduced": "058504edd02667eef8fac9be27ab3ea74332e9b4", "fixed": "c5157b3e775dac31d51b11f993a06a84dc11fc8c" } +}, { + "type": "SEMVER", + "introduced": "1.0.0", + "fixed": "1.0.2", +}, { + "type": "SEMVER", + "introduced": "1.1.0", + "fixed": "1.1.3", }] ``` @@ -881,12 +897,20 @@ We now have: ``` "ranges": [{ - "type: "SEMVER", + "type: "GIT", "events": [ { "introduced": "058504edd02667eef8fac9be27ab3ea74332e9b4" }, { "fixed": "3533e50cbee8ff086bfa04176ac42a01ee3db37d" }, { "fixed": "c5157b3e775dac31d51b11f993a06a84dc11fc8c" } ] +}, { + "type: "SEMVER", + "events": [ + { "introduced": "1.0.0" }, + { "fixed": "1.0.2" }, + { "introduced": "1.1.0" }, + { "fixed": "1.1.3" } + ] }] ``` From bb2ea1bee61d2426df09e25b1a86a41e0d4d8b91 Mon Sep 17 00:00:00 2001 From: Oliver Chang Date: Wed, 18 Aug 2021 14:22:23 +1000 Subject: [PATCH 13/22] clarifications --- schema.md | 45 +++++++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/schema.md b/schema.md index 459d3073..51eebcd1 100644 --- a/schema.md +++ b/schema.md @@ -67,7 +67,6 @@ contain UTF-8 text. "ranges": [ { "type": string, "repo": string, - "earlier_affected": bool, "events": [ { "introduced": string, "fixed": string @@ -272,24 +271,21 @@ package ecosystem. The `affected` object's `ranges` field is a JSON array of objects describing the affected ranges of versions. -#### affected[].ranges[].earlier_affected field - -The `ranges` object's `earlier_affected` field is a boolean value. If this is -`false` (the default), this means that any versions before the listed `events` -versions should be considered unaffected. Otherwise, these versions should be -considered affected. - #### affected[].ranges[].events field The `ranges` object's `events` field is a JSON array of objects. Each object -describes a single version that either introduces, or fixes a vulnerability (but -**not both**). +describes a single version that either: +- introduces a vulnerability, `{"introduced": "1.0.0"}`, or +- fixes a vulnerability, `{"fixed": "1.0.2"}` + +Only **a single verson** (either "introduced" or "fixed") is allowed in each event +object. `{"introduced": "1.0.0", "fixed": "1.0.2"}` is **invalid**. For example, the following expresses that versions in the SemVer ranges `[1.0.0, 1.0.2)` or `[1.1.1, 1.1.5)` are affected. Everything else is unaffected. ``` -"ranges": [{ +"ranges": [ { "type: "SEMVER", "events": [ { "introduced": "1.0.0" }, @@ -297,13 +293,13 @@ For example, the following expresses that versions in the SemVer ranges `[1.0.0, { "introduced": "1.1.1" }, { "fixed": "1.1.5" } ] -}] +} ] ``` An algorithm for computing if a version `v` is affected can be done as follows: ``` -affected = ranges.earlier_affected +affected = false for evt in sorted(ranges.events) if evt.introduced && v >= evt.introduced affected = true @@ -315,6 +311,23 @@ return affected Here the meaning of the relation `u >= v` and `sorted()` depends on the type. +A special event value of `{ "introduced": "*"}` is allowed. `"*"` is a special +version that sorts before any other version. This can be used to indicate that +all prior versions are considered vulnerable. + +For example, to express that all versions before `1.0.2` is vulnerable, one may +write: + +``` +"ranges": [ { + "type: "SEMVER", + "events": [ + { "introduced": "*" }, + { "fixed": "1.0.2" }, + ] +} ] +``` + #### affected[].ranges[].type field In the `ranges` field, the `type` field is required. It specifies the type of @@ -612,7 +625,10 @@ format. Here’s an example entry: "ranges": [ { "type": "SEMVER", - "events": [ {"fixed": "0.1.20"} ] + "events": [ + {"introduced": "*"}, + {"fixed": "0.1.20"} + ] } ], "ecosystem_specific": { @@ -652,6 +668,7 @@ potential encoding of a vulnerability entry. "type": "GIT", "repo": "https://github.com/pikepdf/pikepdf", "events": [ + { "introduced": "*" }, { "fixed": "3f38f73218e5e782fe411ccbb3b44a793c0b343a" } ], }, From 6d2c44d9c48ae84872b86f3d8a1e0e15a00b3c39 Mon Sep 17 00:00:00 2001 From: Oliver Chang Date: Wed, 18 Aug 2021 14:27:03 +1000 Subject: [PATCH 14/22] more clarifications --- schema.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/schema.md b/schema.md index 51eebcd1..8ee6f3d5 100644 --- a/schema.md +++ b/schema.md @@ -284,7 +284,7 @@ object. `{"introduced": "1.0.0", "fixed": "1.0.2"}` is **invalid**. For example, the following expresses that versions in the SemVer ranges `[1.0.0, 1.0.2)` or `[1.1.1, 1.1.5)` are affected. Everything else is unaffected. -``` +```json "ranges": [ { "type: "SEMVER", "events": [ @@ -296,11 +296,12 @@ For example, the following expresses that versions in the SemVer ranges `[1.0.0, } ] ``` -An algorithm for computing if a version `v` is affected can be done as follows: +An algorithm for computing if a version `v` is affected by a range can be done +as follows: ``` affected = false -for evt in sorted(ranges.events) +for evt in sorted(range.events) if evt.introduced && v >= evt.introduced affected = true else if evt.fixed && v >= evt.fixed @@ -318,7 +319,7 @@ all prior versions are considered vulnerable. For example, to express that all versions before `1.0.2` is vulnerable, one may write: -``` +```json "ranges": [ { "type: "SEMVER", "events": [ From 73c9ffe49c4f6b13eb5f5ec7f7dda8908443603e Mon Sep 17 00:00:00 2001 From: Oliver Chang Date: Wed, 18 Aug 2021 14:27:43 +1000 Subject: [PATCH 15/22] typo --- schema.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/schema.md b/schema.md index 8ee6f3d5..46ba8b50 100644 --- a/schema.md +++ b/schema.md @@ -195,8 +195,8 @@ needed. The `versions` field can enumerate a specific set of affected versions, and the `ranges` field can list ranges of affected versions, under a given defined -ordering. A version is considered affected if it lies within any one of the -ranges or is listed in the versions list. +ordering. **A version is considered affected if it lies within any one of the +ranges or is listed in the versions list.** The `versions` list should - with one exception - always be present, to allow software to answer the question "is this specific version affected?" without @@ -286,7 +286,7 @@ For example, the following expresses that versions in the SemVer ranges `[1.0.0, ```json "ranges": [ { - "type: "SEMVER", + "type": "SEMVER", "events": [ { "introduced": "1.0.0" }, { "fixed": "1.0.2" }, @@ -296,8 +296,7 @@ For example, the following expresses that versions in the SemVer ranges `[1.0.0, } ] ``` -An algorithm for computing if a version `v` is affected by a range can be done -as follows: +An algorithm for computing if a version `v` is affected by a range follows: ``` affected = false @@ -312,7 +311,7 @@ return affected Here the meaning of the relation `u >= v` and `sorted()` depends on the type. -A special event value of `{ "introduced": "*"}` is allowed. `"*"` is a special +A special event value of `{ "introduced": "*" }` is allowed. `"*"` is a special version that sorts before any other version. This can be used to indicate that all prior versions are considered vulnerable. @@ -321,7 +320,7 @@ write: ```json "ranges": [ { - "type: "SEMVER", + "type": "SEMVER", "events": [ { "introduced": "*" }, { "fixed": "1.0.2" }, From 6a3160bfe3791a0cd794e4b9d7dc4b11b7d522cf Mon Sep 17 00:00:00 2001 From: Oliver Chang Date: Thu, 19 Aug 2021 12:13:19 +1000 Subject: [PATCH 16/22] tentative: "reverse" flag --- schema.md | 67 +++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 58 insertions(+), 9 deletions(-) diff --git a/schema.md b/schema.md index 46ba8b50..f8986f54 100644 --- a/schema.md +++ b/schema.md @@ -67,6 +67,7 @@ contain UTF-8 text. "ranges": [ { "type": string, "repo": string, + "reverse": boolean, "events": [ { "introduced": string, "fixed": string @@ -271,7 +272,7 @@ package ecosystem. The `affected` object's `ranges` field is a JSON array of objects describing the affected ranges of versions. -#### affected[].ranges[].events field +#### affected[].ranges[].reverse, affected[].ranges[].events fields The `ranges` object's `events` field is a JSON array of objects. Each object describes a single version that either: @@ -296,7 +297,17 @@ For example, the following expresses that versions in the SemVer ranges `[1.0.0, } ] ``` -An algorithm for computing if a version `v` is affected by a range follows: +The `ranges` object's `reverse` field is an optional boolean that determines +the algorithm to evaluate whether a given version is impacted. + +If not set explicitly, a default value will be inferred from the provided +`events`: +- After sorting, if the first event is an `introduced`, then `reverse` is + `false`. +- Otherwise, `reverse` is `true`. + +If `reverse` is `false`, then the algorithm to evaluate if `v` is impacted by a +range is: ``` affected = false @@ -309,25 +320,63 @@ for evt in sorted(range.events) return affected ``` -Here the meaning of the relation `u >= v` and `sorted()` depends on the type. +If `reverse` is `true`, then the algorithm to evaluate if `v` is impacted by a +range is: + +``` +affected = false +for evt in reversed(sorted(range.events)) + if evt.introduced && v < evt.introduced + affected = false + else if evt.fixed && v < evt.fixed + affected = true + +return affected +``` -A special event value of `{ "introduced": "*" }` is allowed. `"*"` is a special -version that sorts before any other version. This can be used to indicate that -all prior versions are considered vulnerable. +The two algorithms are very similar for range types that have a linear +ordering (i.e. most numbered versioning schemes). -For example, to express that all versions before `1.0.2` is vulnerable, one may -write: +This allows entries such as the following to mean "everything prior to `1.0.2`" +is affected. If instead `reverse` is `false`, then the algorithm will evaluate +this to "nothing is affected". ```json "ranges": [ { "type": "SEMVER", + # implicit: "reverse": true, "events": [ - { "introduced": "*" }, { "fixed": "1.0.2" }, ] } ] ``` +For range types such as `GIT`, which only allows a partial ordering of commits, +`reverse` has larger implications on how we compute the affected range of +commits. + +Given the following commit graph and ranges, + +![git graph](images/git_graph.png) + +```json +"ranges": [ { + "type": "GIT", + "events": [ + { "introduced": "X" }, + { "fixed": "Y" }, + ] +} ] +``` + +If `reverse` is `false`, the list of computed affected commits will be `X, A, B, +C, D, E, F`. This is the desired behaviour is most cases. + +If `reverse` is `true`, the list of affected commits will be `X, A, B, C`. This +is equivalent to `git rev-list X..Y` (but including `X` and not including `Y`). +This may be useful if the scope of a vulnerability entry is limited to a single +linear branch. + #### affected[].ranges[].type field In the `ranges` field, the `type` field is required. It specifies the type of From c25efee6853b4c3b76b823c2daba2deefc77dce2 Mon Sep 17 00:00:00 2001 From: Oliver Chang Date: Thu, 19 Aug 2021 12:14:05 +1000 Subject: [PATCH 17/22] add git graph --- images/git_graph.png | Bin 0 -> 6727 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 images/git_graph.png diff --git a/images/git_graph.png b/images/git_graph.png new file mode 100644 index 0000000000000000000000000000000000000000..a9af0ac5f6d1f86e7b76bcd9f44948e6dbc14b8e GIT binary patch literal 6727 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 Date: Thu, 19 Aug 2021 13:45:31 +1000 Subject: [PATCH 18/22] clarification --- schema.md | 60 +++++++++++++++++++++++++++---------------------------- 1 file changed, 29 insertions(+), 31 deletions(-) diff --git a/schema.md b/schema.md index f8986f54..83133088 100644 --- a/schema.md +++ b/schema.md @@ -272,7 +272,7 @@ package ecosystem. The `affected` object's `ranges` field is a JSON array of objects describing the affected ranges of versions. -#### affected[].ranges[].reverse, affected[].ranges[].events fields +#### affected[].ranges[].events fields The `ranges` object's `events` field is a JSON array of objects. Each object describes a single version that either: @@ -297,16 +297,7 @@ For example, the following expresses that versions in the SemVer ranges `[1.0.0, } ] ``` -The `ranges` object's `reverse` field is an optional boolean that determines -the algorithm to evaluate whether a given version is impacted. - -If not set explicitly, a default value will be inferred from the provided -`events`: -- After sorting, if the first event is an `introduced`, then `reverse` is - `false`. -- Otherwise, `reverse` is `true`. - -If `reverse` is `false`, then the algorithm to evaluate if `v` is impacted by a +In most cases, the algorithm to evaluate if `v` is impacted by a range is: ``` @@ -320,13 +311,37 @@ for evt in sorted(range.events) return affected ``` +A special event value of `{"introduced": "*"}` can be used to indicate a version +that sorts before any other version. + +This allows entries such as the following to mean "everything before `1.0.2`" is +affected. + +```json +"ranges": [ { + "type": "SEMVER", + "events": [ + { "introduced": "*" }, + { "fixed": "1.0.2" }, + ] +} ] +``` + +#### affected[].ranges[].reverse + +The `ranges` object's `reverse` field is an optional boolean that determines +the algorithm to evaluate whether a given version is impacted. The default is +`false` which results in the semantics as described in the previous section. + If `reverse` is `true`, then the algorithm to evaluate if `v` is impacted by a -range is: +range is instead: ``` affected = false for evt in reversed(sorted(range.events)) - if evt.introduced && v < evt.introduced + if evt.introduced && v == evt.introduced + affected = true + else if evt.introduced && v < evt.introduced affected = false else if evt.fixed && v < evt.fixed affected = true @@ -334,25 +349,8 @@ for evt in reversed(sorted(range.events)) return affected ``` -The two algorithms are very similar for range types that have a linear -ordering (i.e. most numbered versioning schemes). - -This allows entries such as the following to mean "everything prior to `1.0.2`" -is affected. If instead `reverse` is `false`, then the algorithm will evaluate -this to "nothing is affected". - -```json -"ranges": [ { - "type": "SEMVER", - # implicit: "reverse": true, - "events": [ - { "fixed": "1.0.2" }, - ] -} ] -``` - For range types such as `GIT`, which only allows a partial ordering of commits, -`reverse` has larger implications on how we compute the affected range of +`reverse` has large implications on how we compute the affected range of commits. Given the following commit graph and ranges, From 9537676499d55c3dac75517287352395860de4e1 Mon Sep 17 00:00:00 2001 From: Oliver Chang Date: Thu, 19 Aug 2021 14:26:51 +1000 Subject: [PATCH 19/22] minor nit --- schema.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schema.md b/schema.md index 83133088..16d3bf88 100644 --- a/schema.md +++ b/schema.md @@ -371,7 +371,7 @@ If `reverse` is `false`, the list of computed affected commits will be `X, A, B, C, D, E, F`. This is the desired behaviour is most cases. If `reverse` is `true`, the list of affected commits will be `X, A, B, C`. This -is equivalent to `git rev-list X..Y` (but including `X` and not including `Y`). +is equivalent to `git rev-list X..Y` (but including `X` and excluding `Y`). This may be useful if the scope of a vulnerability entry is limited to a single linear branch. From 5b39f491d0d33cab9f11a9a955f1e181ca9a4cff Mon Sep 17 00:00:00 2001 From: Oliver Chang Date: Tue, 24 Aug 2021 17:43:19 +1000 Subject: [PATCH 20/22] Remove "reverse". Use "limit" instead. --- schema.md | 276 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 170 insertions(+), 106 deletions(-) diff --git a/schema.md b/schema.md index 16d3bf88..6298763a 100644 --- a/schema.md +++ b/schema.md @@ -1,6 +1,6 @@ # Open Source Vulnerability format -**Version 0.8 (August 17, 2021)** +**Version 0.8 (August 24, 2021)** Original authors: - Oliver Chang (ochang@google.com) @@ -67,10 +67,10 @@ contain UTF-8 text. "ranges": [ { "type": string, "repo": string, - "reverse": boolean, "events": [ { "introduced": string, "fixed": string + "limit": string } ] } ], "versions": [ string ], @@ -214,7 +214,7 @@ enumerated `versions` list, although they can also add ranges of type In short, each object in the `affected` array must contain either a non-empty `versions` list or at least one range in the `ranges` list of type `SEMVER`. -#### affected[].package field +### affected[].package field The `affected` object's `package` field is a JSON object identifying the affected code library or command provided by the package. The object itself has @@ -261,61 +261,129 @@ It is permitted for a database name (the DB prefix in the `id` field) and an ecosystem name to be the same, provided they have the same owner who can make decisions about the meaning of the `ecosystem_specific` field (see below). -#### affected[].versions field +### affected[].versions field The `affected` object's `versions` field is a JSON array of strings. Each string is a single affected version in whatever version syntax is used by the given package ecosystem. -#### affected[].ranges[] field +### affected[].ranges[] field The `affected` object's `ranges` field is a JSON array of objects describing the affected ranges of versions. -#### affected[].ranges[].events fields +### affected[].ranges[].type field + +In the `ranges` field, the `type` field is required. It specifies the type of +version range being recorded and defines the interpretation of the `events` +object's `introduced`, `fixed`, and any type-specific fields. + +The defined types and their additional fields are: + +- `SEMVER`: The versions `introduced` and `fixed` are semantic versions as defined +by [SemVer 2.0.0](https://semver.org), with no leading "v" prefix. The relation +`u < v` denotes the precedence order defined in [section 11 of SemVer 2.0](https://semver.org/#spec-item-11). +Ranges listed with type `SEMVER` should not overlap: since SEMVER is a strict +linear ordering, it is always possible to simplify to non-overlapping ranges. + + Specifying one or more `SEMVER` ranges removes the requirement to specify an +explicit enumerated `versions` list (see the discussion above). + +- `ECOSYSTEM`: The versions `introduced` and `fixed` are arbitrary, uninterpreted +strings specific to the package ecosystem, which does not conform to SemVer +2.0’s version ordering. + + Specifying one or more `ECOSYSTEM` ranges does NOT remove the requirement to +specify an explicitly enumerated `versions` list, because `ECOSYSTEM` range +inclusion queries cannot be answered without reference to the package +ecosystem’s own logic and therefore cannot be used by ecosystem-independent +processors. + +- `GIT`: The versions `introduced` and `fixed` are full-length Git commit + hashes. The repository’s commit graph is needed to evaluate whether a given + version is in the range. The relation `u < v` is true when commit `u` is a + (perhaps distant) parent of commit `v`. + + Specifying one or more `GIT` ranges does NOT remove the requirement to specify +an explicitly enumerated `versions` list, because `GIT` range inclusion queries +cannot be answered without access to a copy of the underlying Git repository. + +Again, it is important to note that to allow portable (non-ecosystem-specific) +processors to answer "is this version affected?", either `SEMVER` ranges or an +explicit `versions` list must be given. The `ECOSYSTEM` and `GIT` ranges +are only for adding additional context. + +### affected[].ranges[].events fields The `ranges` object's `events` field is a JSON array of objects. Each object describes a single version that either: -- introduces a vulnerability, `{"introduced": "1.0.0"}`, or -- fixes a vulnerability, `{"fixed": "1.0.2"}` +- Introduces a vulnerability: `{"introduced": string}` +- Fixes a vulnerability: `{"fixed": string}` +- Sets an upper limit on the range being described: `{"limit": string}`. + +These `events` objects represent a "timeline" of status changes for the affected +package. + +The values of "introduced", "fixed" and "limit" are version strings as defined +by the `affected[].ranges[].type` field. Additionally, + - `"introduced"` allows a version of the value `"\*"` to represent a version that + sorts before any other version. + - `"limit"` allows versions containing the string `"\*"` to represent "infinity". + If no limit events are provided, an implicit `{ "limit": "*" }` is assumed to + exist. Multiple `"limit"` events are allowed in the same range. + +Only **a single type** (either `"introduced"`, `"fixed"`, `"limit"`) is allowed in +each event object. For instance, `{"introduced": "1.0.0", "fixed": "1.0.2"}` is +**invalid**. -Only **a single verson** (either "introduced" or "fixed") is allowed in each event -object. `{"introduced": "1.0.0", "fixed": "1.0.2"}` is **invalid**. +There must be at least one `"introduced"` or `"fixed"` object in the `events` +array. While not required, it's also recommended to keep the `events` array +sorted according to the `affected[].ranges[].type` of the range. -For example, the following expresses that versions in the SemVer ranges `[1.0.0, -1.0.2)` or `[1.1.1, 1.1.5)` are affected. Everything else is unaffected. +The algorithm to evaluate if `v` is impacted by a range is: + +``` +func GetFirstVersion(events) + for evt in sorted(events) + if evt.introduced is present + return evt.introduced + + if evt.fixed is present + return evt.fixed + +func FitsRange(v, range) + firstVersion = GetFirstVersion(range.events) + beforeAnyLimit = false + + for evt in range.events + if evt.limit is present and v < evt.limit + beforeAnyLimit = true + + return v >= firstVersion && beforeAnyLimit + +vulnerable = false +for range in affected.ranges + if FitsRange(v, range) + for evt in sorted(range.events) + if evt.introduced is present && v >= evt.introduced + vulnerable = true + else if evt.fixed is present && v >= evt.fixed + vulnerable = false +``` + +#### Examples +The following expresses that "every possible version is affected". ```json "ranges": [ { "type": "SEMVER", "events": [ - { "introduced": "1.0.0" }, - { "fixed": "1.0.2" }, - { "introduced": "1.1.1" }, - { "fixed": "1.1.5" } + { "introduced": "*" }, ] } ] ``` -In most cases, the algorithm to evaluate if `v` is impacted by a -range is: - -``` -affected = false -for evt in sorted(range.events) - if evt.introduced && v >= evt.introduced - affected = true - else if evt.fixed && v >= evt.fixed - affected = false - -return affected -``` - -A special event value of `{"introduced": "*"}` can be used to indicate a version -that sorts before any other version. - -This allows entries such as the following to mean "everything before `1.0.2`" is -affected. +The following expresses that "everything before `1.0.2`" is affected. ```json "ranges": [ { @@ -327,33 +395,55 @@ affected. } ] ``` -#### affected[].ranges[].reverse +The following expresses that versions in the SemVer ranges `[1.0.0, +1.0.2)` or `[3.0.0, 3.2.5)` are affected. Everything else is unaffected. -The `ranges` object's `reverse` field is an optional boolean that determines -the algorithm to evaluate whether a given version is impacted. The default is -`false` which results in the semantics as described in the previous section. +```json +"ranges": [ { + "type": "SEMVER", + "events": [ + { "introduced": "1.0.0" }, + { "fixed": "1.0.2" }, + { "introduced": "3.0.0" }, + { "fixed": "3.2.5" } + ] +} ] +``` -If `reverse` is `true`, then the algorithm to evaluate if `v` is impacted by a -range is instead: +We can also use `limit` to further divide up the timeline into sub-ranges +(e.g. branches). -``` -affected = false -for evt in reversed(sorted(range.events)) - if evt.introduced && v == evt.introduced - affected = true - else if evt.introduced && v < evt.introduced - affected = false - else if evt.fixed && v < evt.fixed - affected = true - -return affected +```json +"ranges": [ + { + "type": "SEMVER", + "events": [ + { "introduced": "1.0.0" }, + { "fixed": "1.0.2" }, + { "limit": "1.*" }, + ] + }, + { + "type": "SEMVER", + "events": [ + { "introduced": "3.0.0" }, + { "fixed": "3.2.5" }, + { "limit": "3.*" }, + ] + }, +] ``` -For range types such as `GIT`, which only allows a partial ordering of commits, -`reverse` has large implications on how we compute the affected range of -commits. +This means: +- Within the `1.0.0` to `1.*` range, anything prior to `1.0.2` is affected. +- Within the `3.0.0` to `3.*` range, anything prior to `3.2.5` is affected. -Given the following commit graph and ranges, +While the algorithm outputs the same result for the both representations, the +one with the "limit" makes it more explicit which version branches are +explicitly known. + +For git ranges, `limit` has more implications for the evaluation algorithm. Take +the following git commit graph and git range: ![git graph](images/git_graph.png) @@ -367,55 +457,28 @@ Given the following commit graph and ranges, } ] ``` -If `reverse` is `false`, the list of computed affected commits will be `X, A, B, -C, D, E, F`. This is the desired behaviour is most cases. - -If `reverse` is `true`, the list of affected commits will be `X, A, B, C`. This -is equivalent to `git rev-list X..Y` (but including `X` and excluding `Y`). -This may be useful if the scope of a vulnerability entry is limited to a single -linear branch. - -#### affected[].ranges[].type field - -In the `ranges` field, the `type` field is required. It specifies the type of -version range being recorded and defines the interpretation of the `events` -object's `introduced`, `fixed`, and any type-specific fields. - -The defined types and their additional fields are: - -- `SEMVER`: The versions `introduced` and `fixed` are semantic versions as defined -by [SemVer 2.0.0](https://semver.org), with no leading "v" prefix. The relation -`u >= v` denotes the precedence order defined in [section 11 of SemVer 2.0](https://semver.org/#spec-item-11). - - Specifying one or more `SEMVER` ranges removes the requirement to specify an -explicit enumerated `versions` list (see the discussion above). - -- `ECOSYSTEM`: The versions `introduced` and `fixed` are arbitrary, uninterpreted -strings specific to the package ecosystem, which does not conform to SemVer -2.0’s version ordering. - - Specifying one or more `ECOSYSTEM` ranges does NOT remove the requirement to -specify an explicitly enumerated `versions` list, because `ECOSYSTEM` range -inclusion queries cannot be answered without reference to the package -ecosystem’s own logic and therefore cannot be used by ecosystem-independent -processors. +Without an explicit `limit`, the list of computed affected commits will be `X, +A, B, C, D, E, F`. This is the desired behaviour is most cases. -- `GIT`: The versions `introduced` and `fixed` are full-length Git commit - hashes. The repository’s commit graph is needed to evaluate whether a given - version is in the range. The relation `u >= v` is true when commit `u` is - either the exact same commit as `v`, or `v` is a (perhaps distant) parent of - commit `u`. +```json +"ranges": [ { + "type": "GIT", + "events": [ + { "introduced": "X" }, + { "limit": "Y" }, + ] +} ] +``` - Specifying one or more `GIT` ranges does NOT remove the requirement to specify -an explicitly enumerated `versions` list, because `GIT` range inclusion queries -cannot be answered without access to a copy of the underlying Git repository. +If `limit` is set to `Y`, the list of affected commits will be `X, A, B, C`. This +is equivalent to `git rev-list X..Y` (but including `X` and excluding `Y`). +This may be useful if the scope of a vulnerability entry is limited to a small +set of linear branches. Multiple `"limit"` events may be specified for each +branch. -Again, it is important to note that to allow portable (non-ecosystem-specific) -processors to answer "is this version affected?", either `SEMVER` ranges or an -explicit `versions` list must be given. The `ECOSYSTEM` and `GIT` ranges -are only for adding additional context. +Note that we did not specify a `fixed` event here as `limit` makes it redundant. -#### affected[].ranges[].repo field +### affected[].ranges[].repo field The `ranges` object's `repo` field is the URL of the package's code repository. The value should be in a format that's directly usable as an @@ -427,8 +490,7 @@ describing a single range. The range object defines the fields `type`, This field is required if `affected[].ranges[].type` is `GIT`. - -#### affected[].ecosystem_specific field +### affected[].ecosystem_specific field The `affected` object's `ecosystem_specific` field is a JSON object holding additional information about the vulnerability as defined by the ecosystem for @@ -442,7 +504,7 @@ the Go project-specific severity scale. Note that this is a single field with key "ecosystem_specific", which itself contains a JSON object with unspecified fields. -#### affected[].database_specific field +### affected[].database_specific field The `affected` object's `database_specific` field is a JSON object holding additional information about the vulnerability as defined by the database from @@ -913,7 +975,7 @@ My plan is to rewrite the italicized paragraph at the top of the doc on Monday and then share the link publicly to gather more feedback from groups that have not yet seen it. -## Status - 2021-08-05 +## Status - 2021-08-24 The biggest change to the schema is our decision to support multiple packages and ecosystems per entry and the way we specify version ranges. @@ -979,7 +1041,9 @@ We now have: ``` This avoids repetition with the previous approach and better fits non-linear -versioning schemes like git ranges. +versioning schemes like git ranges. We also introduced a "limit" event, which +allows git range specification to be scoped to a small num single branch. This was not +possible before. These are breaking changes, but we hope to make migration easier by renaming the "affects" field to "affected" to allow existing consumers and producers of this From 0a6e1c91d101825aa9b067360176c95ff5a291b2 Mon Sep 17 00:00:00 2001 From: Oliver Chang Date: Wed, 25 Aug 2021 15:00:49 +1000 Subject: [PATCH 21/22] small clarifications --- schema.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/schema.md b/schema.md index 6298763a..89f8b3bd 100644 --- a/schema.md +++ b/schema.md @@ -438,12 +438,12 @@ This means: - Within the `1.0.0` to `1.*` range, anything prior to `1.0.2` is affected. - Within the `3.0.0` to `3.*` range, anything prior to `3.2.5` is affected. -While the algorithm outputs the same result for the both representations, the -one with the "limit" makes it more explicit which version branches are -explicitly known. +While the evaluation algorithm outputs the same result for both representations, +the one with the "limit" makes it more explicit which version branches are +known. -For git ranges, `limit` has more implications for the evaluation algorithm. Take -the following git commit graph and git range: +For git ranges, `limit` has more implications for the result of the evaluation +algorithm. Take the following git commit graph and git range: ![git graph](images/git_graph.png) @@ -458,7 +458,7 @@ the following git commit graph and git range: ``` Without an explicit `limit`, the list of computed affected commits will be `X, -A, B, C, D, E, F`. This is the desired behaviour is most cases. +A, B, C, D, E, F`. This is the desired behaviour in most cases. ```json "ranges": [ { @@ -474,7 +474,7 @@ If `limit` is set to `Y`, the list of affected commits will be `X, A, B, C`. Thi is equivalent to `git rev-list X..Y` (but including `X` and excluding `Y`). This may be useful if the scope of a vulnerability entry is limited to a small set of linear branches. Multiple `"limit"` events may be specified for each -branch. +branch -- each expands the scope of the git commit graph to cover. Note that we did not specify a `fixed` event here as `limit` makes it redundant. From 1261cbfb491969f6ed9ad9e8cb0644d41a83e311 Mon Sep 17 00:00:00 2001 From: Oliver Chang Date: Fri, 27 Aug 2021 07:12:18 +1000 Subject: [PATCH 22/22] Use "0" for beginning of time instead. --- schema.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/schema.md b/schema.md index 89f8b3bd..c59a5564 100644 --- a/schema.md +++ b/schema.md @@ -326,7 +326,7 @@ package. The values of "introduced", "fixed" and "limit" are version strings as defined by the `affected[].ranges[].type` field. Additionally, - - `"introduced"` allows a version of the value `"\*"` to represent a version that + - `"introduced"` allows a version of the value `"0"` to represent a version that sorts before any other version. - `"limit"` allows versions containing the string `"\*"` to represent "infinity". If no limit events are provided, an implicit `{ "limit": "*" }` is assumed to @@ -378,7 +378,7 @@ The following expresses that "every possible version is affected". "ranges": [ { "type": "SEMVER", "events": [ - { "introduced": "*" }, + { "introduced": "0" }, ] } ] ``` @@ -389,7 +389,7 @@ The following expresses that "everything before `1.0.2`" is affected. "ranges": [ { "type": "SEMVER", "events": [ - { "introduced": "*" }, + { "introduced": "0" }, { "fixed": "1.0.2" }, ] } ] @@ -735,7 +735,7 @@ format. Here’s an example entry: { "type": "SEMVER", "events": [ - {"introduced": "*"}, + {"introduced": "0"}, {"fixed": "0.1.20"} ] } @@ -777,7 +777,7 @@ potential encoding of a vulnerability entry. "type": "GIT", "repo": "https://github.com/pikepdf/pikepdf", "events": [ - { "introduced": "*" }, + { "introduced": "0" }, { "fixed": "3f38f73218e5e782fe411ccbb3b44a793c0b343a" } ], },