brew-vulns
A Homebrew subcommand that checks installed packages for known vulnerabilities using the OSV.dev database.
Installation
Via Homebrew:
brew install homebrew/brew-vulns/brew-vulns
Or via RubyGems:
gem install brew-vulns
Once installed, the command is available as brew vulns.
Usage
brew vulns [formula...] [options]
Options
| Flag | Long form | Description |
|---|---|---|
--all |
Scan every formula in homebrew-core | |
-b PATH |
--brewfile PATH |
Scan packages from a Brewfile (default: ./Brewfile) |
-d |
--deps |
Include dependencies when checking a specific formula or Brewfile |
--no-ignore-patches |
Report vulnerabilities even when the formula applies a patch that resolves them | |
-j |
--json |
Output results as JSON |
--cyclonedx |
Output results as CycloneDX SBOM with vulnerabilities | |
--sarif |
Output results as SARIF for GitHub code scanning | |
-m N |
--max-summary N |
Truncate summaries to N characters (default: 60, 0 for no limit) |
-s LEVEL |
--severity LEVEL |
Only show vulnerabilities at or above LEVEL (low, medium, high, critical) |
-h |
--help |
Show help message |
Examples
# Check all installed packages
brew vulns
# Scan every formula in homebrew-core
brew vulns --all --json > vulns.json
# Check a specific formula (does not need to be installed)
brew vulns openssl
# Check several formulae at once
brew vulns vim curl jq
# Check a formula and its dependencies
brew vulns python --deps
# Scan packages from a Brewfile
brew vulns --brewfile
# Scan a specific Brewfile
brew vulns -b ~/project/Brewfile
# Scan Brewfile packages and their dependencies
brew vulns --brewfile --deps
# Output as JSON (useful for CI/CD)
brew vulns --json
# Show longer summaries
brew vulns --max-summary 100
# Show full summaries (no truncation)
brew vulns -m 0
# Only show HIGH and CRITICAL vulnerabilities
brew vulns --severity high
# Output as CycloneDX SBOM with vulnerabilities
brew vulns --cyclonedx > sbom.cdx.json
# Output as SARIF for GitHub code scanning
brew vulns --sarif > results.sarif
# Show help
brew vulns --help
How it works
- Reads Homebrew formulae via
brew info --json=v2(installed packages by default, or any named formulae passed as arguments) - Extracts the repository URL and version tag from each formula's source URL
- Queries the OSV API using the GIT ecosystem to find known vulnerabilities
- Reports any vulnerabilities found with their severity and CVE identifiers
Packages with GitHub, GitLab, or Codeberg source URLs are checked. Packages from other sources are skipped.
Patched vulnerabilities
Some Homebrew formulae apply patches that fix CVEs without changing the upstream version number. Where a formula's patch block declares (or infers) a resolves entry for a CVE or GHSA identifier, brew vulns treats matching OSV results as already resolved: they are listed separately in text and --json output, omitted from --sarif output, emitted in --cyclonedx output with analysis.state set to resolved, and do not affect the exit code. The CycloneDX SBOM also records each formula's patches under components[].pedigree.patches. Pass --no-ignore-patches to report them as open findings instead.
This relies on patches[].resolves data in brew info --json=v2, available from Homebrew 6.0.4 onwards. With an older Homebrew, or for formulae whose patches are not yet annotated, no suppression happens.
Example output
Checking 104 packages for vulnerabilities...
(119 packages skipped - no supported source URL)
expat (2.7.3)
CVE-2025-66382 (HIGH) - XML parsing vulnerability...
hdf5 (1.14.6)
OSV-2023-1091 (MEDIUM) - Buffer overflow in...
OSV-2023-1223 (MEDIUM) - ...
Found 15 vulnerabilities in 3 packages
Exit codes
0- No vulnerabilities found1- Vulnerabilities found2- An error occurred (network failure,brewfailure, parse error)
This makes it suitable for use in CI/CD pipelines. To let a job continue when vulnerabilities are found but still fail on scan errors, use brew vulns ... || [ $? -eq 1 ].
GitHub Actions
Use the --sarif flag to integrate with GitHub code scanning:
name: Vulnerability Scan
on:
schedule:
- cron: '0 0 * * *'
workflow_dispatch:
jobs:
scan:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: Install brew-vulns
run: gem install brew-vulns
- name: Run vulnerability scan
run: brew vulns --sarif > results.sarif || [ $? -eq 1 ]
- name: Upload SARIF results
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: results.sarif
Dependency graph integration
Use the --cyclonedx flag to submit an SBOM to GitHub's dependency graph:
name: SBOM Submission
on:
schedule:
- cron: '0 0 * * *'
workflow_dispatch:
jobs:
sbom:
runs-on: macos-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- name: Install brew-vulns
run: gem install brew-vulns
- name: Generate SBOM
run: brew vulns --cyclonedx > sbom.cdx.json || [ $? -eq 1 ]
- name: Submit to dependency graph
uses: evryfs/sbom-dependency-submission-action@v0
with:
sbom-files: sbom.cdx.json
This adds your Homebrew packages to the repository's dependency graph, enabling Dependabot alerts.
See examples/ for workflows that check changed formulae on tap pull requests and publish a daily scan of all of homebrew-core.
Development
git clone https://github.com/Homebrew/homebrew-brew-vulns
cd brew-vulns
bin/setup
rake test
License
MIT License. See LICENSE for details.