A flexible, lightweight shell script to detect vulnerable npm packages. Includes built-in GHSA and OSV vulnerability feeds with 200,000+ vulnerabilities, or use your own custom databases.
package-checker.sh scans your JavaScript/TypeScript projects for vulnerable dependencies. Works with npm, Yarn, pnpm, Bun, and Deno projects.
- Built-in Vulnerability Feeds: GHSA and OSV feeds with 200,000+ npm vulnerabilities included (auto-updated every 12 hours)
- Docker Images Available: Full image (~43MB with feeds) or lightweight (~27MB)
- Custom Data Sources: Add your own JSON, CSV, or PURL vulnerability lists
- Scanner Integration: Consume SARIF, SBOM, or Trivy JSON from external tools
- Version Ranges: Define ranges like
>=1.0.0 <2.0.0instead of listing every version - Multiple Package Managers: Full support for npm, Yarn (Classic & Berry/v2+), pnpm, Bun, and Deno
- GitHub Integration: Scan entire organizations or individual repositories directly from GitHub
- Zero Dependencies: Only requires
bash,awk, andcurl - Flexible Configuration: Use CLI arguments or
.package-checker.config.jsonfile
- bash β Shell interpreter
- awk (gawk or mawk) β Usually pre-installed
- curl β For remote sources and GitHub API
- Or use Docker images (no installation required)
The easiest way to install and use package-checker:
# Install package-checker
brew install maxgfr/tap/package-checker
# Use it directly (uses default GHSA feed automatically)
package-checker
# Or explicitly specify GHSA feed
package-checker --default-source-ghsa
# Or with both GHSA and OSV feeds
package-checker --default-source-ghsa-osv
# Check specific package version
package-checker --package-name express --package-version 4.17.1
# Scan with custom vulnerability file
package-checker --source custom-vulns.jsonRun directly from the web with your own vulnerability data:
# Run with remote vulnerability source
curl -sS https://raw.githubusercontent.com/maxgfr/package-checker.sh/main/script.sh | bash -s -- --source https://raw.githubusercontent.com/maxgfr/package-checker.sh/refs/heads/main/data/ghsa.purl
# Or with local source file
curl -sS https://raw.githubusercontent.com/maxgfr/package-checker.sh/main/script.sh | bash -s -- --source ./vulns.jsonThe easiest way to get started with built-in vulnerability feeds:
# Scan current directory (uses default GHSA feed automatically)
docker run -v $(pwd):/workspace ghcr.io/maxgfr/package-checker.sh:latest
# Or explicitly use GHSA feed
docker run -v $(pwd):/workspace ghcr.io/maxgfr/package-checker.sh:latest --default-source-ghsa
# Or use both GHSA and OSV feeds for comprehensive coverage
docker run -v $(pwd):/workspace ghcr.io/maxgfr/package-checker.sh:latest --default-source-ghsa-osv
# Scan a specific subdirectory
docker run -v $(pwd):/workspace ghcr.io/maxgfr/package-checker.sh:latest /workspace/my-project --default-source-ghsa-osv
# Use with your own data files
docker run -v $(pwd):/workspace ghcr.io/maxgfr/package-checker.sh:latest --source my-vulns.json# Scan current directory (uses default GHSA source automatically)
package-checker
# Scan specific directory (relative or absolute path)
package-checker ./my-project
package-checker /absolute/path/to/project
# Use both GHSA and OSV sources for comprehensive coverage
package-checker --default-source-ghsa-osv
# Use only OSV source instead of default GHSA
package-checker --default-source-osv
# Check specific package version
package-checker --package-name express --package-version 4.17.1
# Check with version ranges
package-checker --package-name lodash --package-version '^4.17.0'
# Scan with custom vulnerability file
package-checker --source custom-vulns.json
# Scan specific folder with custom source
package-checker ./subfolder --source custom-vulns.json
# Multiple sources (built-in + custom)
package-checker --default-source-ghsa-osv --source custom-vulns.csv
# Use configuration file
package-checker --config .package-checker.config.json
# Scan GitHub organization
package-checker --default-source-ghsa-osv --github-org myorg --github-token $GITHUB_TOKENARGUMENTS:
PATH Directory to scan (default: current directory)
Can be relative (./my-project) or absolute (/path/to/project)
OPTIONS:
-h, --help Show help message
-s, --source SOURCE Vulnerability source (repeatable for multiple sources)
--default-source-ghsa Use default GHSA source (default if no source specified)
--default-source-osv Use default OSV source
--default-source-ghsa-osv Use both default GHSA and OSV sources (recommended for comprehensive coverage)
-f, --format FORMAT Data format: json, csv, purl, sarif, sbom-cyclonedx, or trivy-json (auto-detected from extension)
--csv-columns COLS CSV columns: "name,versions" or "1,2"
--package-name NAME Check vulnerability for a specific package name
--package-version VER Check specific version (requires --package-name)
-c, --config FILE Path to configuration file
--no-config Skip loading configuration file
--export-json FILE Export vulnerability results to JSON format (default: vulnerabilities.json)
--export-csv FILE Export vulnerability results to CSV format (default: vulnerabilities.csv)
--github-org ORG GitHub organization to scan
--github-repo owner/repo Single GitHub repository to scan
--github-token TOKEN GitHub token (or use GITHUB_TOKEN env var)
--github-output DIR Output directory for fetched files (default: ./packages)
--github-only Only fetch from GitHub, skip local analysis
--create-multiple-issues Create one GitHub issue per vulnerable package (requires --github-token)
--create-single-issue Create a single consolidated issue with all vulnerabilities (requires --github-token)
--fetch-all DIR Fetch all vulnerability feeds (osv.purl, ghsa.purl) to specified directory
--fetch-osv FILE Fetch OSV vulnerability feed to specified file
--fetch-ghsa FILE Fetch GHSA vulnerability feed to specified file
--only-package-json Scan only package.json files (skip lockfiles)
--only-lockfiles Scan only lockfiles (skip package.json files)
--lockfile-types TYPES Comma-separated list of lockfile types to scan (npm, yarn, pnpm, bun, deno)
package-checker.sh supports multiple vulnerability data formats:
Built-in feeds (recommended):
data/ghsa.purl- GitHub Security Advisories (~5,000 vulnerabilities)data/osv.purl- Open Source Vulnerabilities (~207,000 vulnerabilities)
Custom formats:
- JSON - Simple key-value format with version ranges
- CSV - Tabular format (name, versions)
- PURL - Package URL standard format
- SARIF - Static analysis results (Trivy, Semgrep, CodeQL)
- SBOM CycloneDX - Software Bill of Materials
- Trivy JSON - Native Trivy output format
JSON format:
{
"express": {
"versions": ["4.16.0", "4.16.1"],
"versions_range": [">=4.0.0 <4.17.21"]
}
}CSV format:
name,versions
express,4.16.0
lodash,">=4.17.0 <4.17.21"PURL format:
pkg:npm/lodash@4.17.20
pkg:npm/express@>=4.0.0 <4.17.21
pkg:npm/@babel/traverse@7.23.0
Configuration file (.package-checker.config.json):
{
"sources": [
{
"source": "https://example.com/vulnerabilities.json",
"name": "Company Security Database"
}
],
"options": {
"ignore_paths": ["node_modules", ".yarn", ".git", "dist"]
}
}For complete format specifications, see the Data Formats documentation.
Lockfiles (exact version matching):
package-lock.json,npm-shrinkwrap.json(npm)yarn.lock(Yarn Classic & Yarn Berry/v2+)pnpm-lock.yaml(pnpm)bun.lock(Bun)deno.lock(Deno)
package.json (dependency checking):
dependencies,devDependencies,optionalDependencies,peerDependencies
By default, package-checker scans both lockfiles and package.json files. You can control what gets scanned:
Scan only package.json files:
# Skip all lockfiles, only scan package.json
package-checker --source vulns.json --only-package-jsonScan only lockfiles:
# Skip package.json files, only scan lockfiles
package-checker --source vulns.json --only-lockfilesScan specific lockfile types:
# Only scan yarn.lock files
package-checker --source vulns.json --lockfile-types yarn
# Only scan npm and yarn lockfiles (skip pnpm, bun, deno)
package-checker --source vulns.json --lockfile-types npm,yarn
# Combine with --only-lockfiles
package-checker --source vulns.json --only-lockfiles --lockfile-types yarnAvailable lockfile types: npm, yarn, pnpm, bun, deno
You can export scan results to JSON or CSV format for further analysis, reporting, or integration with other tools.
Export to JSON:
# Export with custom filename
package-checker --source vulns.json --export-json results.jsonExport to CSV:
# Export with custom filename
package-checker --source vulns.json --export-csv results.csvExport both formats:
package-checker --source vulns.json --export-json output.json --export-csv output.csvJSON Export Format:
The JSON export includes detailed vulnerability information with metadata:
{
"vulnerabilities": [
{
"package": "express@4.16.0",
"file": "./package-lock.json",
"severity": "medium",
"ghsa": "GHSA-rv95-896h-c2vc",
"cve": "CVE-2022-24999",
"source": "ghsa"
}
],
"summary": {
"total_unique_vulnerabilities": 5,
"total_occurrences": 12
}
}CSV Export Format:
The CSV export includes the same metadata in a tabular format:
package,file,severity,ghsa,cve,source
express@4.16.0,./package-lock.json,medium,GHSA-rv95-896h-c2vc,CVE-2022-24999,ghsa
lodash@4.17.20,./package-lock.json,high,GHSA-p6mc-m468-83gw,CVE-2020-8203,ghsaNotes:
- Exports only include packages where vulnerabilities were found
- Metadata fields (severity, GHSA, CVE, source) are included when available in the vulnerability database
- See the Data Formats documentation for details on adding metadata to your vulnerability sources
Use the reusable GitHub Actions workflow for zero-config vulnerability scanning:
name: Security Check
on:
push:
branches: [ main ]
pull_request:
workflow_dispatch:
schedule:
- cron: '0 0 * * 1' # Weekly on Monday
jobs:
vulnerability-check:
uses: maxgfr/package-checker.sh/.github/workflows/reusable-check.yml@main
with:
use-osv: true # Add OSV in addition to default GHSA
fail-on-vulnerabilities: trueBenefits:
- No installation or configuration required
- Uses built-in GHSA feed by default (auto-updated every 12 hours with 200,000+ vulnerabilities)
- Optionally add OSV feed for even more comprehensive coverage
- Works with npm, Yarn, pnpm, Bun, and Deno projects
- Automatic security reports in PR checks
For more examples and other CI systems (GitLab CI, etc.), see the CI/CD Integration documentation.
Scan an entire organization:
package-checker --github-org myorg --github-token ghp_xxx --source vulns.jsonScan a single repository:
# Public repo (no token needed)
package-checker --github-repo owner/repo --source vulns.json
# Private repo (token required)
package-checker --github-repo owner/private-repo --github-token ghp_xxx --source vulns.jsonFetch only (no analysis):
package-checker --github-org myorg --github-token ghp_xxx --github-only --github-output ./packagesAutomatically create GitHub issues for vulnerabilities:
# Create one issue per vulnerable package
package-checker --github-org myorg --github-token ghp_xxx --source vulns.json --create-multiple-issues
# Create a single consolidated issue with all vulnerabilities
package-checker --github-repo owner/repo --github-token ghp_xxx --source vulns.json --create-single-issueIssue creation modes:
| Flag | Description |
|---|---|
--create-multiple-issues |
Creates one issue per vulnerable package, each with detailed vulnerability info |
--create-single-issue |
Creates one consolidated issue containing all vulnerabilities in a single report |
Both modes include:
- Severity levels with visual indicators (π΄ Critical, π High, π‘ Medium, π’ Low)
- Links to GHSA advisories and CVE details
- Affected files and versions
- Recommendations for remediation
- Automatic labeling with
security,vulnerabilityanddependenciestags
Note: Both flags require a GitHub token with repo scope to create issues.
You can check if a specific package or version is vulnerable without needing a data source or scanning a project:
# Check if a specific version is vulnerable
package-checker --package-name next --package-version 16.0.3
# Check with version ranges
package-checker --package-name lodash --package-version '^4.17.0'
# List all occurrences of a package in your project
package-checker --package-name expressThis feature creates a virtual PURL internally and scans your project for it.
Use cases:
- Pre-installation checks: "Is this version safe before I
npm install?" - Quick lookups: "Which versions of this package are being used?"
- Security research: "Where is this vulnerable package in my codebase?"
- Version range testing: "Does
^4.17.0cover vulnerable versions?"
Supported version ranges:
- Exact versions:
1.2.3 - Greater/less than:
>=1.0.0 <2.0.0 - Tilde ranges:
~1.2.3(equivalent to>=1.2.3 <1.3.0) - Caret ranges:
^1.2.3(equivalent to>=1.2.3 <2.0.0) - Wildcard:
*(matches any version)
For more detailed information, see the docs/ directory:
- Why package-checker.sh? β Learn why this tool exists and how it complements other vulnerability scanners
- Docker Usage β Complete guide to using Docker images
- Data Formats β Complete specification of JSON, CSV, PURL formats
- Vulnerability Feeds β Guide to built-in GHSA/OSV feeds and generating custom feeds
- Vulnerability Scanning Tools β Guide to Trivy, Grype, Syft, OSV-Scanner, and other tools
- Configuration β Detailed configuration reference
- GitHub Integration β Advanced GitHub scanning features
- CI/CD Integration β Examples for GitHub Actions, GitLab CI, and more
- Testing β Testing guide with fixtures and examples
- Contributing β Development workflow, commit conventions, and versioning
- Security Teams: Maintain internal vulnerability databases
- Compliance: Enforce company-specific security policies
- CI/CD Pipelines: Automated vulnerability checks
- Incident Response: Quick scans during security incidents
- Supply Chain Security: Monitor dependencies across multiple projects
MIT License β see the LICENSE file for details.
Questions or issues? Open an issue on GitHub.