diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 87dd87dfd12..3aaa84d272d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ # Contributing -Advisories in this repository come from two places: records generated from `resolves` annotations on `homebrew/core` formula patches, and records contributed directly by pull request. Both live under `advisories/` as [OSV-schema](https://ossf.github.io/osv-schema/) JSON and are validated against that schema on every push. +Advisories in this repository come from three places: records generated from `resolves` annotations on `homebrew/core` formula patches, candidate records matched against external OSV feeds by `brew advisory-match`, and records contributed directly by pull request. All live under `advisories/` as [OSV-schema](https://ossf.github.io/osv-schema/) JSON and are validated against that schema on every push. ## Reporting a fixed vulnerability @@ -31,6 +31,33 @@ Name the file `BREW-0000-0000.json`; a maintainer assigns the final id on merge. Use `{"introduced": "0"}` if every shipped version is affected. Omit the `fixed` event if there is no fixed version yet; add it in a follow-up PR once one exists. Versions are the formula version as `brew info` reports it, with an `_N` suffix when the revision is nonzero. Link the upstream CVE, GHSA or advisory in `upstream` and `references`. +## Reviewing matched candidates + +Records with `"database_specific": {"source": "matched", ...}` are produced by `brew advisory-match` (in [Homebrew/brew](https://github.com/Homebrew/brew)), which queries OSV.dev's GIT, language-registry and distro ecosystems plus [CPANSA](https://github.com/briandfoy/cpan-security-advisory) for a formula and emits one candidate per CVE reached. These arrive as automated PRs and need a human to confirm the match before merge. + +`database_specific` tells you how the match was made: + +- `strategy` is the highest-precision path that reached the CVE: `git` (the formula's forge repo), `registry` (a PyPI/npm/crates/... package derived from `stable.url` or a `resource`), `cpansa` (a CPAN distribution), or `distro` (a Debian/Ubuntu/... source package name mapped via [Repology](https://repology.org)). +- `confidence` follows from strategy and whether a comparable version range was found: `high` for `git`/`registry` with a range, `medium` when no comparable range was found (typically GIT commit-SHA events), `low` for `distro`. +- `upstream_evidence` lists every path that reached the CVE, each with the `{ecosystem, name, subject_version}` that was queried. + +`affected[0].ecosystem_specific` tells you what the range check concluded: + +- `range_state` is `affected` (the shipped version is inside an upstream affected range), `fixed` (past one), or absent (no comparable range; the reviewer sets the boundary). +- `upstream_fixed_in` is the upstream version the matched range says fixes it. +- `resource` and `resource_purl` are set when the affected subject is a vendored `resource` block rather than the formula's primary source. +- `"fix": "bump"` and a `fixed` event in `ranges` are only present when `range_state` is `"fixed"`. + +Before merging, check: + +- The `upstream_evidence` keys point at this formula's actual upstream. A `distro`-only hit can reach a CVE for an unrelated package that shares a Repology project (for example a `wget2` CVE surfaced against `wget`); close those. +- The CVE is not a distro-specific patch. Open and confirm the affected package and description match the upstream project, not a distribution's packaging of it. +- If `range_state` is `"fixed"`, the `fixed` boundary in `ranges` is the `pkg_version` at which Homebrew first shipped the fix. `brew advisory-match` derives this by walking `homebrew-core` history; spot-check it against `git log -p -- Formula//.rb` in a `homebrew-core` checkout and correct it in the PR if wrong. The corrected value is preserved on subsequent regenerations. +- If `range_state` is `"affected"` with a `resource`, `brew info --json=v2 | jq '.formulae[0].resources[] | select(.name == "") | .version'` confirms the pinned resource version is below `upstream_fixed_in`. Known false-positive sources are stale CPANSA ranges and OSV records where one alias (often a PYSEC id) has an open-ended range while another has a bounded one. +- If `range_state` is absent and `confidence` is `medium` or `low`, the record is a lead rather than a determination: either set the `ranges` boundary yourself from the upstream advisory and `homebrew-core` history, or close if the CVE does not apply. + +Do not merge a `matched` record over an existing `source: "generated"` record for the same `(formula, CVE)`; the generated record already states Homebrew ships a patch and takes precedence. `brew advisory-match --output` skips these automatically. + ## Scope Records here describe vulnerabilities in software Homebrew distributes, scoped to the Homebrew formula name and version. They are not a substitute for the upstream project's own advisory; the purpose is to let tools that read `pkg:brew` purls or `Homebrew` OSV queries answer "is this installed formula affected". Casks are out of scope for now.