Expose formula patches in the JSON API (and optionally annotate them with CVEs) #6869
Replies: 11 comments 6 replies
-
|
Yeh, these both make sense to me! PRs welcome. |
Beta Was this translation helpful? Give feedback.
-
|
PR for part one: Homebrew/brew#22459 |
Beta Was this translation helpful? Give feedback.
-
|
22459 merged, patch data now in the api:
Example from llvm: next up, part 2 |
Beta Was this translation helpful? Give feedback.
-
|
Part 2 patch to add |
Beta Was this translation helpful? Give feedback.
-
|
PR for part two: Homebrew/brew#22466 Ended up going with patch do
url "https://deb.debian.org/.../libquicktime_1.2.4-12.debian.tar.xz"
sha256 "..."
type :backport
resolves "CVE-2016-2399", "CVE-2017-9122"
apply "patches/CVE-2016-2399.patch", "patches/CVE-2017-9122_et_al.patch"
end
"type": "backport",
"resolves": [
{"type": "security", "id": "CVE-2016-2399"},
{"type": "security", "id": "CVE-2017-9122"}
]The inference Mike suggested is in there too: CVE ids found in the patch |
Beta Was this translation helpful? Give feedback.
-
|
For backfilling the existing 1,191 patches across 809 formulae, here's where the data sits today and where By patch kind
External patches by source (n=972)
Already inferable with no formula changes (once #22466 lands): 25 unique CVEs across The 497 GitHub commit patches are the big prize for automation since OSV indexes fix-commits → CVEs directly. The 272 Homebrew-hosted raw patches are almost entirely macOS/compiler build fixes and will mostly end up with no |
Beta Was this translation helpful? Give feedback.
-
|
Homebrew/brew#22466 has been merged and shipped in homebrew 6.0.4 now, I've rebased Homebrew/homebrew-core#285534, if this is looking good I can start to roll through more and more of the formula with patches to add them in |
Beta Was this translation helpful? Give feedback.
-
|
Wired this up on the Testing it against the four formulae from Homebrew/homebrew-core#285534 turned up an OSV coverage gap worth noting. Most CVE records in OSV are auto-converted from NVD and have no That points at a possible third part to this thread: now that formulae carry structured |
Beta Was this translation helpful? Give feedback.
-
|
Picking up the backfill that Homebrew/homebrew-core#285534 floats for the remaining ~935 patch blocks (scripted by URL heuristic): I pulled the API patch data to scope it and it gave me pause. I sampled 59 of the upstream-commit patches and zero reference a CVE. Core patches are mostly build/portability fixes, not security backports, so a URL/filename heuristic finds very little beyond the cases already covered (the CVE-named patchsets like unzip that inference catches, plus the four you annotated by hand). And of the ~10 formulae that mention a CVE in source, most are outstanding/unfixed CVEs or version rationale (avahi, openslp, sylpheed, opentsdb), so a heuristic that greps for CVE strings risks injecting false "patched" signals. So rather than scripting blind, I'd make it scanner-driven: run I can drop a per-patch inventory into a tracking issue as the working set and open the first batch from the scanner output once #92 / #93 land. Sound right, or do you still want the URL-heuristic sweep as a first pass and treat the scanner run as validation on top? |
Beta Was this translation helpful? Give feedback.
-
|
Status update on the three parts. Part 1/2 (patches in JSON, Backfill (Homebrew/homebrew-brew-vulns#95): ran the scanner-driven pass over the 484 patched formulae that are currently queryable. 9 had OSV hits; every shipped patch turned out to be a build/portability fix, so zero new Part 3 (Homebrew OSV feed): prototyped. Homebrew/homebrew-brew-vulns#99 adds Plan is to transfer that repo into the Homebrew org once it's settled, then open the osv.dev new-data-source request and the ossf/osv-schema registration PR from there. |
Beta Was this translation helpful? Give feedback.
-
|
Quick update since the last one, mostly on part 3.
Backfill: #97 (homepage fallback) merged, which made 20 of the previously-skipped 314 patched formulae queryable. Re-scan found zero OSV hits for any of them, so still one net annotation ( Next: transfer |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
While working on
brew-vulnsI wanted to find every formula in homebrew-core that ships with a patch applied. There's currently no way to get this frombrew info --jsonor formulae.brew.sh;Formula#to_hashdoesn't serialisepatchlist, and formulae loaded from the API have an emptypatchlist. The only options today are grepping a homebrew-core checkout forpatch do/patch :DATA, or runningbrew rubywithHOMEBREW_NO_INSTALL_FROM_API=1and walkingFormula.all. Roughly 860 of the ~8400 core formulae currently carry at least one patch.1. Add a
patcheskey toFormula#to_hash. Something like:This would let
brew-vulnsand other downstream tooling (SBOM generators, OSV importers, distro-comparison tools) see which packages Homebrew has modified relative to the upstream tarball, without needing a full core checkout.2. Allow patches to declare which CVEs they address. Right now this lives in comments:
glibcapplies a Debian patch tarball withapply "patches/any/CVE-2024-2961.patch",libquicktimehas# Fix CVE-2016-2399above itspatch doblock. Only about eight formulae mention a CVE at all, and where the data exists it can't be read programmatically. A small DSL addition would cover it:which would surface in the JSON as
"fixes": ["CVE-2016-2399", "CVE-2017-9122"]on each patch entry. This is the same shape Fedora uses in spec changelogs and Alpine uses insecfixes:blocks, and it would let vulnerability scanners report "yes this version is affected upstream, but Homebrew's bottle is patched" instead of raising a false positive. Related: in #6826 @SMillerDev suggested handling CVEs at the audit layer; structured patch data would give that audit something to read.I'm happy to put together the PR for part 1 if there's appetite; part 2 is more of a policy question about whether maintainers want to track that data in formulae at all.
Beta Was this translation helpful? Give feedback.
All reactions