| # Vulnerability Report Format & Style Guide | |
| The Go security team uses an internal YAML format to create vulnerability | |
| reports, which are automatically converted to OSV JSON and served to the | |
| vulnerability database at [vuln.go.dev](https://vuln.go.dev). | |
| The YAML format is subject to change without warning and should not be | |
| relied on by external tools. (See [go.dev/security/vuln/database](https://go.dev/security/vuln/database) for information on the public Go Vulnerability | |
| database API and the OSV schema.) | |
| This page documents the fields of the internal YAML file format. | |
| ## `id` | |
| type `string` | |
| **required** | |
| The unique Go identifier assigned to this report. | |
| This is automatically assigned via `vulnreport create`. It should be of | |
| the form `GO-YYYY-NNNN` where `YYYY` is the year the report was created, | |
| and `NNNN` is the x/vulndb issue tracker number associated with the report. | |
| ## `modules` | |
| type `[]module` | |
| **required** | |
| Information on each Go module affected by the vulnerability. | |
| ### `module.module` | |
| type `string` | |
| **required** | |
| The module path of the vulnerable module. | |
| Use `"std"` for vulnerabilities in the standard library. | |
| Use `"cmd"` for vulnerabilities in the Go tools (`cmd/...`). | |
| ### `module.versions` | |
| type `[]version` | |
| The version ranges in which the package is vulnerable. | |
| If omitted, it is assumed that _every_ version of the module is | |
| vulnerable. | |
| Versions must be SemVer 2.0.0 versions, with no "v" or "go" prefix. | |
| Version ranges must not overlap. | |
| Don't expend effort finding the first `introduced` version unless | |
| it's obvious. | |
| The version ranges in announcements, CVE text, GHSAs, and so forth are | |
| frequently wrong. Always verify the fixed version from the repository history. | |
| If the vulnerability is fixed in multiple minor versions, define sorted, | |
| non-overlapping version ranges thats describe the affected revisions. | |
| For example, for a fix in 1.17.2, 1.18.4, and 1.19.0: | |
| ```yaml | |
| - fixed: 1.17.2 | |
| - introduced: 1.18.0 | |
| fixed: 1.18.4 | |
| ``` | |
| Note that we don't need to mention 1.19.0 in the version ranges, since it | |
| comes after 1.18.4. | |
| #### `version.introduced` | |
| type `string` | |
| The version at which the vulnerability was introduced. | |
| If this field is omitted, it is assumed that every version, from the | |
| initial commit, up to the `fixed` version is vulnerable. | |
| #### `version.fixed` | |
| type `string` | |
| The version at which the vulnerability was fixed. | |
| If this field is omitted, it is assumed that every version since the | |
| `introduced` version is vulnerable. | |
| ### `module.non_go_versions` | |
| type `string` | |
| (Optional - used only in special cases, usually for binary reports.) | |
| The non-Go version range(s) at which the package is vulnerable. | |
| A non-Go version range can be used to specify versions used by | |
| module maintainers that do not conform to [Go's module | |
| version conventions](https://go.dev/doc/modules/version-numbers). | |
| An example is data/reports/GO-2024-2539.yaml, whose vulnerable versions | |
| are listed as: | |
| ```yaml | |
| versions: | |
| - fixed: 1.1.2-0.20230830170046-f4cf4c6de017 | |
| non_go_versions: | |
| - fixed: 4.0.0-rc2 | |
| vulnerable_at: 1.1.2-0.20230829214939-57856e474934 | |
| ``` | |
| The [GHSA](https://github.com/advisories/GHSA-4fp6-574p-fc35) for this report | |
| lists a fixed version, `4.0.0-rc2`, which is not known to the module proxy. | |
| To encode this, we list that version as a "non-Go" version, and put the | |
| pseudo-version corresponding to the fix commit in the regular `versions` section. | |
| ### `module.vulnerable_at` | |
| type `string` | |
| The version at which the vulnerable symbols were obtained. Ideally, this | |
| is the version just prior to the fix. | |
| In many cases, this can be inferred automatically via `vulnreport fix`. | |
| ### `module.vulnerable_at_requires` | |
| type `[]string` | |
| List of module@version to require when performing static analysis. | |
| It is rare that we need to specify this. | |
| Example from [GO-2021-0072](../data/reports/GO-2021-0072.yaml): | |
| ```yaml | |
| vulnerable_at_requires: | |
| - github.com/Sirupsen/logrus@v1.0.6 | |
| ``` | |
| ### `module.packages` | |
| type `[]package` | |
| **required** | |
| Information on each package affected by the vulnerability. | |
| Include every importable package containing a root vulnerable symbol. | |
| If `"internal/foo".F` is vulnerable and `"foo".F` calls it, only include | |
| the innermost (internal) package. | |
| If a vulnerability occurs in multiple major versions of a module, | |
| include an entry for each major version. | |
| #### `package.package` | |
| type `string` | |
| **required** | |
| The import path of the vulnerable package. | |
| #### `package.symbols` | |
| type `[]string` | |
| The symbols affected by this vulnerability. | |
| If included, only programs which use these symbols will be marked as | |
| vulnerable. If omitted, any program which imports this module will be | |
| marked vulnerable. | |
| These should be the symbols initially detected or identified in the CVE | |
| or other source. | |
| #### `package.derived_symbols` | |
| type `[]string` | |
| Derived symbols that are calculated from `symbols`, | |
| such as by static analysis tools like `govulncheck`. | |
| This is generated automatically by the `vulnreport fix` command. | |
| Don't edit this field manually. | |
| Potentially, the set of derived symbols can differ with the module | |
| version. We don't attempt to capture that level of detail. Most of the | |
| values of `derived_symbols` as of this writing were obtained from a | |
| module version that was just prior to the version that the report | |
| listed as fixed. | |
| #### `package.skip_fix` | |
| type `string` | |
| A text justification for why static analysis should not be performed | |
| on this package (perhaps because it causes an error). It is rare | |
| that we need to specify this. | |
| ## `summary` | |
| type `string` | |
| **required** | |
| A short (<=100 characters) textual description of the vulnerability, | |
| usually of the form "PROBLEM in MODULE(s)", e.g: | |
| `summary: "Man-in-the-middle attack in golang.org/x/crypto/ssh`. | |
| To allow for easy visual differentiation, each report must have a unique | |
| summary. | |
| ## `description` | |
| type `string` | |
| **required** if first-party. | |
| Optional for third-party when there is an advisory link. | |
| A textual description of the vulnerability and its impact. Should be | |
| wrapped to 80 columns. Does not use Markdown formatting. | |
| The first paragraph should be a short, succinct description of the | |
| nature and impact of the vulnerability, ideally one line. Assume | |
| the person reading this knows what the vulnerable package does. | |
| Use additional paragraphs to describe the issue in more detail as | |
| necessary. | |
| Use the present tense: "This is vulnerable" rather than "this was | |
| vulnerable". | |
| This field may be omitted for third-party reports that have an | |
| external canonical advisory linked in the references section. | |
| ## `published` | |
| type `time.Time` | |
| (Handled automatically, do not edit manually) | |
| Date the report was added to the vulnerability database. | |
| This is normally determined from the git repository history, and | |
| does not need to be set in the report YAML except when the first | |
| commit of the report YAML doesn't match the publication date. | |
| Older reports moved from a previous location have this set. | |
| ## `last_modified` | |
| type `time.Time` | |
| (Handled automatically, do not edit manually) | |
| Last time the report was changed. This is normally determined from | |
| the repository history, and does not need to be set in the report | |
| YAML. | |
| ## `cves` | |
| type `[]string` | |
| The Common Vulnerabilities and Exposures (CVE) ID(s) for the | |
| vulnerability. | |
| ## `ghsas` | |
| type `[]string` | |
| The GitHub Security Advisory (GHSA) IDs for the vulnerability. | |
| ## `credits` | |
| type `[]string` | |
| The name(s) of the person/organization that discovered/reported the | |
| vulnerability. | |
| This should be filled in for Go project reports (standard library, | |
| golang.org/x, etc.). Use the text from the golang-announce email | |
| when available. | |
| For third-party reports, if `vulnreport create` finds CVE or GHSA metadata, use | |
| that. Also, look for a "Credits" heading on the GHSA report linked from the | |
| GitHub issue. Otherwise, it's okay to leave this blank. | |
| ## `references` | |
| type `[]reference` | |
| Links to further information about the vulnerability. | |
| Include a `fix` link to the fix pull request, Gerrit code review, or commit. | |
| No need to link both the PR and the commit. | |
| Prefer to link to the PR or code review rather than the commit. | |
| Don't include links to CVEs and GHSAs just because they exist. | |
| (That's what the cve/ghsa fields are for.) | |
| DO include an `advisory` link to an authoritative *first-party* | |
| advisory when one exists. | |
| If the first-party advisory is a GHSA, then link to that. | |
| If the first-party advisory is a CVE, then link to the CVE page on | |
| nvd.nist.gov/vuln. | |
| Include a `report` link to a first-party bug or issue when one exists. | |
| Don't include links to random third-party issue trackers (e.g., | |
| Debian announcements). CVEs often contain a bunch of random links | |
| of dubious value; be aggressive in pruning these out. | |
| The internal representation of a `Reference` is a struct with `Type` | |
| and `URL` fields. For convenience, the YAML representation is a | |
| single-element map from type to URL. For example: | |
| ```yaml | |
| references: | |
| - fix: https://go.dev/cl/25010 | |
| - report: https://go.dev/issue/16405 | |
| ``` | |
| ### `reference.type` | |
| type `string` | |
| The type of reference, as in the | |
| [OSV references field](https://ossf.github.io/osv-schema/#references-field). | |
| OSV types are upper-case, but the type in the YAML should be lower case. | |
| Types we use: | |
| * `ADVISORY`: A link to an authoritative, first-party advisory. | |
| * `ARTICLE`: An article or blog post about the vulnerability. | |
| * `REPORT`: A bug or issue tracker link. | |
| * `FIX`: A link to the PR/CL which fixes the vulnerability. | |
| * `PACKAGE`: The home page for the package. (We usually do not include this.) | |
| * `EVIDENCE`: A demonstration of the vulnerability. (We usually do not include this.) | |
| * `WEB`: Anything that doesn't fit into the above. | |
| ### `reference.url` | |
| type `string` | |
| The URL of the reference. | |
| ## `cve_metadata` | |
| type `cve_metadata` | |
| Information used to generate a CVE record based on this report. This | |
| should be populated only if the Go CNA assigned the CVE for this report. | |
| ### `cve_metadata.id` | |
| type `string` | |
| The CVE ID assigned by the Go CNA for this report. | |
| ### `cve_metadata.cwe` | |
| type `string` | |
| The [CWE](https://cwe.mitre.org/index.html) most closely associated | |
| with this vulnerability, of the form "CWE-XXX: Description". | |
| ### `cve_metadata.description` | |
| type `string` | |
| The description of the vulnerability to use in the CVE record. If blank, | |
| the top-level description is used. | |
| This was used to preserve existing descriptions. For new reports, this | |
| does not need to be set. | |
| ### `cve_metadata.references` | |
| type `[]string` | |
| References that should be published in the CVE record, but not the OSV | |
| record. This is used to preserve references added by the CVE program, | |
| and is rarely used. | |
| Example: [GO-2022-0476](../data/reports/GO-2022-0476.yaml) | |
| ## `notes` | |
| type `[]string` | |
| Optional, freeform notes about the report. This field is ignored when creating | |
| OSV and CVE records, so it does not need to be polished. | |
| It can be used to document decisions made when creating the report, | |
| outstanding issues, or anything else worth mentioning. | |
| ## `source` | |
| **required** for new reports | |
| Auto-generated metadata indicating the source of this report. | |
| ### `source.id` | |
| type `string` | |
| The CVE or GHSA ID of the vulnerability used to generate this report. | |
| For original reports, this is "go-security-team". | |
| ### `source.created` | |
| type `string` | |
| The timestamp at which the report was generated based on the indicated source. | |
| ## `review_status` | |
| type `string` | |
| **required** | |
| The status of this report, either UNREVIEWED, NEEDS_REVIEW, or REVIEWED. | |
| Unreviewed reports are generally auto-generated or nearly so. Their | |
| details have not been verified and no attempt has been made to determine | |
| packages or symbols. These reports must have an advisory link. | |
| Needs review reports are like unreviewed reports in that they are auto-generated, | |
| but we plan to review them in the near future. They have stricter requirements | |
| for version data than unreviewed reports. The NEEDS_REVIEW status allows us to | |
| quickly publish initial versions of most reports that will require review. | |
| NEEDS_REVIEW is an internal status only: it is converted to UNREVIEWED when | |
| published to OSV. | |
| Reviewed reports are reports for which we have made a good faith effort | |
| to determine correct affected versions, packages, and symbols. (In some | |
| cases it is not possible to determine all of these, which is OK). Descriptions | |
| are optional, except for reports affecting the Go standard library, toolchain | |
| or x/ repos. | |
| ## `excluded` | |
| type `string` | |
| A reason the report is excluded from the database. | |
| When a CVE or GHSA is evaluated and determined to be out of scope | |
| for the Go Vulnerability Database, the reason for excluding it may | |
| be recorded in a report. This report should include a value for the | |
| `excluded` enum (this field) as well as a list of CVEs and/or GHSAs. | |
| Excluded reports are placed in the `excluded/` directory. | |
| Valid values are: | |
| * `NOT_GO_CODE`: The vulnerability is not in a Go package, and | |
| cannot affect any Go packages. (For example, a vulnerability in | |
| a C++ library.) | |
| * `NOT_IMPORTABLE`: The vulnerability occurs in package `main`, | |
| an `internal/` package only imported by package `main`, or some | |
| other location which can never be imported by another module. | |
| * `EFFECTIVELY_PRIVATE`: While the vulnerability occurs in a Go | |
| package which can be imported by another module, the package is | |
| not intended for external use and is not likely to ever be imported | |
| outside the module in which it is defined. | |
| * `DEPENDENT_VULNERABILITY`: This vulnerability is a subset of another | |
| vulnerability in the database. For example, if package A contains a | |
| vulnerability, package B depends on package A, and there are separate | |
| CVEs for packages A and B, we might mark the report for B as a dependent | |
| vulnerability entirely superseded by the report for A. | |
| * `NOT_A_VULNERABILITY`: While a CVE or GHSA has been assigned, | |
| there is no known vulnerability associated with it. | |
| * `WITHDRAWN`: The source report for this vulnerability was withdrawn | |
| before a report was published in vulndb. (If a source report is withdrawn | |
| after a report is published, we withdraw the report too). | |
| * `LEGACY_FALSE_POSITIVE`: This is the label used for excluded reports | |
| that were marked as false positive in the initial triage process (in 2020), | |
| before we stored excluded reports in the repo. This label must not be used | |
| for any new reports. | |
| ## Example Reports | |
| * Standard library: [GO-2021-0067](../data/reports/GO-2021-0067.yaml) | |
| * Toolchain: [GO-2021-0068](../data/reports/GO-2021-0068.yaml) | |
| * x/ repo: [GO-2020-0012](../data/reports/GO-2020-0012.yaml) | |
| * Third-party: [GO-2021-0075](../data/reports/GO-2021-0075.yaml) | |
| * Excluded:[GO-2022-0559](../data/excluded/GO-2022-0559.yaml) |